home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / utility / winnav.zip / WINNAC.ZIP / WINNAV.C next >
C/C++ Source or Header  |  1991-11-20  |  73KB  |  2,473 lines

  1. //========================================================================
  2. //
  3. //  WINNAV.C -- A File manager for Microsoft Windows
  4. //
  5. //  (c) Douglas Boling, 1991
  6. //
  7. //
  8. //  Set tab stops to every 3 spaces for better readability
  9. //
  10. //========================================================================
  11.  
  12. #define  BUTTONWIDTH     80
  13. #define  BUTTONHEIGHT    50
  14.  
  15. #define  BUTTONMAX      10
  16. #define  LBOXMAX        10
  17.  
  18. #include <dos.h>
  19. #include <windows.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <direct.h>
  24. #include <errno.h>
  25.  
  26. #define  STRTOLP(l)        ((LONG)(LPSTR)(l))
  27.  
  28. #include "winnav.h"
  29.  
  30. //------------------------------------------------------------------------
  31. //Control Window Procedure pointers used in subclassing
  32. //------------------------------------------------------------------------
  33. FARPROC    lpfnOldLBoxProc[LBOXMAX+1];
  34. FARPROC    lpfnOldEditBoxProc;
  35.  
  36. FARPROC    lpfnListBoxSubclassProc;
  37. FARPROC    lpfnEditBoxSubclassProc;
  38.  
  39. //------------------------------------------------------------------------
  40. //Global Data used to manipulate child Windows
  41. //------------------------------------------------------------------------
  42. int   sLBoxCount = LBOXMAX;
  43. int    sLBoxVStart = 0;
  44.  
  45. typedef struct {
  46.     DWORD    lSize;
  47.     WORD    wDate;
  48.     WORD    wTime;
  49.     WORD    wAttr;
  50.     char    szName[13];
  51. } FILEINFO;
  52.  
  53. //typedef FILEINFO *PFILEINFO;
  54. typedef struct find_t FIND_T;
  55. typedef struct DOSERROR DOSERR;
  56. typedef struct diskfree_t DISKFREE_T;
  57.  
  58.  
  59. struct LISTBOXSTRUCT {
  60.     char    szPath [128];
  61.     char    szSel [16];
  62. } lsLBoxes [LBOXMAX];
  63.  
  64. int   sLBoxVisible = 0;
  65. HWND    hwndLBoxArray [LBOXMAX];
  66.  
  67.  
  68. struct BUTTONSTRUCT {
  69.     HWND    hwndButton;
  70.     int    sFunction;
  71. } bsButtons [BUTTONMAX] = {{0, 0},
  72.                            {0, 1},
  73.                            {0, 2},
  74.                            {0, 3},
  75.                            {0, 4},
  76.                            {0, 5},
  77.                            {0, 6},
  78.                            {0, 7},
  79.                            {0, 8},
  80.                            {0, 9}};
  81.  
  82. struct FUNCTIONSTRUCT {
  83.     int    sFunction;
  84.     char    szText [8];
  85. } fsFunctions [10] = {{IDM_OPEN,        "Open"},
  86.                       {IDM_MOVE,        "Move"},
  87.                       {IDM_COPY,        "Copy"},
  88.                       {IDM_RENAME,    "Rename"},
  89.                       {IDM_MKDIR,    "MkDir"},
  90.                       {IDM_DELETE,    "Delete"},
  91.                       {IDM_ATTRIB,    "Attrib"},
  92.                       {IDM_INFO,        "Info"},
  93.                       {IDM_CONFIG,    "Config"},
  94.                       {IDM_EXIT,        "Exit"}};
  95.  
  96. int    sButtonCount;
  97. BOOL    bIncDir;
  98.  
  99. HWND  hwndEditBox;
  100. HWND  hwndScrollBar;
  101. HWND  hwndDrvBox;
  102.  
  103. HWND    hwndFocusWin;
  104.  
  105. char    szMasterPath [128];
  106. char    szDestPath [128];
  107. char    szFunction [8];
  108.  
  109. BOOL    bDir;
  110. BOOL    bExecutable;
  111.  
  112. //------------------------------------------------------------------------
  113. //Function prototypes
  114. //------------------------------------------------------------------------
  115. int  PASCAL         WinMain (HANDLE, HANDLE, LPSTR, int);
  116. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);
  117. long FAR PASCAL ListBoxSubclassProc (HWND, WORD, WORD, LONG);
  118. long FAR PASCAL EditBoxSubclassProc (HWND, WORD, WORD, LONG);
  119. long FAR PASCAL ListBoxSubclassProc (HWND, WORD,WORD, LONG);
  120. long FAR PASCAL EditBoxSubclassProc (HWND, WORD,WORD, LONG);
  121. int  FAR PASCAL ConfigDlgProc (HWND,WORD, WORD, LONG);
  122. int  FAR PASCAL CopyRenDlgProc (HWND,WORD, WORD, LONG);
  123. int  FAR PASCAL MkDirDlgProc (HWND,WORD, WORD, LONG);
  124. int  FAR PASCAL SetAttrDlgProc (HWND,WORD, WORD, LONG);
  125. int  FAR PASCAL FileInfoDlgProc (HWND,WORD, WORD, LONG);
  126. int  FAR PASCAL AboutDlgProc (HWND,WORD, WORD, LONG);
  127. long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);
  128.  
  129. int    NumLBoxes (int);
  130. int      LBoxPos (int);
  131. int      LBoxHeight (int);
  132. int      EBoxWidth (int);
  133. int      GetButtonHeight (int);
  134. void  SetButtonPos (int, int);
  135. LONG  SendLBoxMsg (int,WORD, WORD, LONG);
  136. void  GetLBoxText (int, char *);
  137. void  ScrollLBoxes (int);
  138. int    TranslateID (WORD);
  139. void    FillListBox (HWND, char *, int);
  140. int      ParsePath (HWND, int, char *, int);
  141. int    GetDirDepth (void);
  142. void    RefreshListBoxes (HWND);
  143. int    FillListBoxes (HWND);
  144. int    IsProgram (char  *,char  *);
  145. int    EnableButtons (HWND, BOOL, BOOL);
  146. long    GetDiskFree (int);
  147. int    GetFileInfo (char  *, FILEINFO *);
  148. void    ConvertDate (WORD, char *);
  149. void    ConvertTime (WORD, char *);
  150. void  GetFileType (char  *, WORD, char  *, char  *);
  151. int    GetErrorCode (void);
  152. void    PrintError (HWND,int, char  *);
  153. int    MakeDir (char  *);
  154. int    CopyFile (HWND,char  *,char  *);
  155. int    CopyDir (HWND,char  *, char  *, int);
  156. int    DeleteFile (HWND, char  *);
  157. int    DeleteDir (HWND, char  *, int);
  158.  
  159. //------------------------------------------------------------------------
  160. // Child window size data
  161. //------------------------------------------------------------------------
  162. int    sDrvBoxWidth, sLBoxWidth, sEditBoxHeight, sBMinHeight;
  163.  
  164. //------------------------------------------------------------------------
  165. // Configuration data
  166. //------------------------------------------------------------------------
  167. char    szDefaultEditor [80];
  168. int    sSearchFlags;
  169. BOOL    bDirFirst;
  170. BOOL    bConfirmFileDel;
  171. BOOL    bConfirmDirDel;
  172.  
  173. char        szProfileName[] = "WINNAV.INI";
  174. char        szAppName[] = "WinNav";
  175. HANDLE    hInstance;
  176.  
  177. //=======================================================================
  178. //
  179. // Program Entry Point (WinMain)
  180. //
  181. //=======================================================================
  182. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  183.                 LPSTR lpszCmdParam, int nCmdShow) {
  184.  
  185.    HWND        hwnd;
  186.    MSG            msg;
  187.    WNDCLASS    wndclass;
  188.  
  189.     HDC            hdc;
  190.     TEXTMETRIC    tm;
  191.  
  192.     int            i, x, y, cx, cy;
  193.     char        szTemp [32];
  194.  
  195.     if (!hPrevInstance) {
  196.       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  197.       wndclass.lpfnWndProc    = WndProc;
  198.       wndclass.cbClsExtra     = 0;
  199.       wndclass.cbWndExtra     = 0;
  200.       wndclass.hInstance      = hInstance;
  201.       wndclass.hIcon          = LoadIcon (hInstance, szAppName);
  202.       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  203.       wndclass.hbrBackground  = COLOR_WINDOW + 1;
  204.       wndclass.lpszMenuName   = szAppName;
  205.       wndclass.lpszClassName  = szAppName;
  206.  
  207.       RegisterClass (&wndclass);
  208.    }
  209.     //
  210.     //Determine the size of the system font to set the sizes of the
  211.     //window controls.
  212.     //
  213.     hdc = GetDC (GetDesktopWindow());
  214.     SelectObject (hdc, GetStockObject (SYSTEM_FONT));
  215.     GetTextMetrics (hdc, &tm);
  216.     sDrvBoxWidth = tm.tmAveCharWidth * 4;
  217.     sLBoxWidth = tm.tmAveCharWidth * 20;
  218.     sEditBoxHeight = 3 * (tm.tmHeight + tm.tmExternalLeading) / 2;
  219.     sBMinHeight = 3 * (tm.tmHeight + tm.tmExternalLeading) / 2;
  220.     ReleaseDC (GetDesktopWindow(), hdc);
  221.  
  222.     //
  223.     // Get data on the last state of the program.
  224.     //
  225.     x = GetPrivateProfileInt (szAppName, "x", 40, szProfileName);
  226.     y = GetPrivateProfileInt (szAppName, "y", 40, szProfileName);
  227.  
  228.     cx = (3 * (sLBoxWidth+5)) + 15 + BUTTONWIDTH + sDrvBoxWidth
  229.          + (GetSystemMetrics (SM_CXFRAME) * 2);
  230.     cx = GetPrivateProfileInt (szAppName, "cx", cx, szProfileName);
  231.     cy = GetPrivateProfileInt (szAppName, "cy", 400, szProfileName);
  232.  
  233.     sSearchFlags = GetPrivateProfileInt (szAppName, "IncFlags", 6, 
  234.                                          szProfileName);
  235.     bDirFirst = GetPrivateProfileInt (szAppName, "DirFirst", TRUE,
  236.                                       szProfileName);
  237.     bConfirmFileDel = GetPrivateProfileInt (szAppName, "ConfFileDel", TRUE, 
  238.                                             szProfileName);
  239.     bConfirmDirDel = GetPrivateProfileInt (szAppName, "ConfDirDel", TRUE, 
  240.                                            szProfileName);
  241.     GetPrivateProfileString (szAppName, "DefaultEditor" , "notepad.exe",
  242.                              szDefaultEditor, sizeof (szDefaultEditor),
  243.                              szProfileName);
  244.  
  245.     sButtonCount = GetPrivateProfileInt (szAppName, "NumberButtons", 6, 
  246.                                          szProfileName);
  247.     for (i = 0; i < BUTTONMAX; i++) {
  248.         strcpy (szTemp, "Button");
  249.         itoa (i, szTemp+6, 10);
  250.         bsButtons[i].sFunction = GetPrivateProfileInt (szAppName, szTemp, i,
  251.                                                        szProfileName);
  252.     }
  253.    hwnd = CreateWindow (szAppName,            // window class name
  254.                     "WinNav",                  // window caption
  255.                     WS_OVERLAPPEDWINDOW,       // window style
  256.                     x,                         // initial x position
  257.                     y,                         // initial y position
  258.                     cx,                        // initial x size
  259.                     cy,                        // initial y size
  260.                     NULL,                      // parent window handle
  261.                     NULL,                      // window menu handle
  262.                     hInstance,                 // program instance handle
  263.                     NULL);                     // creation parameters
  264.  
  265.     if (!(nCmdShow & SW_SHOWMINIMIZED) &&
  266.         GetPrivateProfileInt (szAppName, "Zoom", 0, szProfileName))
  267.         nCmdShow |= SW_SHOWMAXIMIZED;
  268.  
  269.    ShowWindow (hwnd, nCmdShow);
  270.  
  271.    UpdateWindow (hwnd);
  272.  
  273.    while (GetMessage (&msg, NULL, 0, 0)) {
  274.        TranslateMessage (&msg);
  275.        DispatchMessage (&msg);
  276.    }
  277.    return msg.wParam;
  278. }
  279.  
  280. //========================================================================
  281. //
  282. // Window formatting routines
  283. //
  284. //========================================================================
  285. //------------------------------------------------------------------------
  286. // Routine to compute the proper number of list boxes
  287. //------------------------------------------------------------------------
  288. int NumLBoxes (int sWinWidth) {
  289.  
  290.     int    sCount;
  291.  
  292.     if (sButtonCount)
  293.         sCount = (sWinWidth - BUTTONWIDTH - sDrvBoxWidth - 10) / 
  294.                  (sLBoxWidth+3);
  295.     else
  296.         sCount = (sWinWidth - sDrvBoxWidth - 10) / (sLBoxWidth+3);
  297.     return max (1, sCount);
  298. }
  299.  
  300. //------------------------------------------------------------------------
  301. // Routine to compute the position of a list box
  302. //------------------------------------------------------------------------
  303. int LBoxPos (int sBoxNum) {
  304.  
  305.    return max (1, (10 + (sBoxNum * (sLBoxWidth + 3)) + sDrvBoxWidth));
  306. }
  307.  
  308. //------------------------------------------------------------------------
  309. // Routine to compute the height of the list boxes
  310. //------------------------------------------------------------------------
  311. int LBoxHeight (int sWinHeight) {
  312.  
  313.    return max (0, sWinHeight - (2*sEditBoxHeight) - 20);
  314. }
  315.  
  316. //------------------------------------------------------------------------
  317. // Routine to compute the proper width of the edit box
  318. //------------------------------------------------------------------------
  319. int EBoxWidth (int sLBoxCnt) {
  320.  
  321.    return max (sLBoxWidth, (sLBoxCnt * (sLBoxWidth + 3))) + sDrvBoxWidth + 2;
  322. }
  323.  
  324. //------------------------------------------------------------------------
  325. // Routine to compute the proper width of the edit box
  326. //------------------------------------------------------------------------
  327. int GetButtonHeight (int sWinHeight) {
  328.  
  329.     int    sBHeight;
  330.  
  331.     sBHeight = 0;
  332.     if (sButtonCount) {
  333.         sBHeight = min (((sWinHeight-5)/sButtonCount)-5, BUTTONWIDTH);
  334.         sBHeight = max (sBMinHeight, sBHeight);
  335.     }
  336.     return sBHeight;
  337. }    
  338.  
  339. //------------------------------------------------------------------------
  340. // Set Button Position
  341. //------------------------------------------------------------------------
  342. void SetButtonPos (int sHeight, int sWidth) {
  343.     int    i, sBHeight;
  344.     
  345.     sBHeight = GetButtonHeight (sHeight);
  346.     if (sBHeight) {
  347.  
  348.         for (i = 0; i < sButtonCount; i++)
  349.             SetWindowPos (bsButtons [i].hwndButton, NULL,
  350.                                  sWidth - BUTTONWIDTH - 5, 
  351.                           5 + (i * (sBHeight+5)), 
  352.                           BUTTONWIDTH, sBHeight, 0);
  353.     }
  354. }
  355.  
  356. //========================================================================
  357. //
  358. // Virtual Listbox Support routines
  359. //
  360. //========================================================================
  361. //------------------------------------------------------------------------
  362. // Virtualize listboxes by using this function to send messages to LBoxes
  363. //------------------------------------------------------------------------
  364. LONG SendLBoxMsg (int sLBoxNum, WORD msg, WORD wParam, LONG lParam) {
  365.     LONG    lRetCode;
  366.     
  367.     switch (msg) {
  368.         case LB_DIR:
  369.             strcpy (lsLBoxes[sLBoxNum].szPath, 
  370.                     (char *)LOWORD (lParam));
  371.             lRetCode = 0;
  372.             break;
  373.  
  374.         case LB_SELECTSTRING:
  375.             strcpy (lsLBoxes[sLBoxNum].szSel, 
  376.                     (char *)LOWORD (lParam));
  377.             lRetCode = 0;
  378.             break;
  379.  
  380.         case LB_SETCURSEL:
  381.             if (wParam == -1)
  382.                 strcpy (lsLBoxes[sLBoxNum].szSel, "");
  383.             lRetCode = 0;
  384.             break;
  385.  
  386.         case LB_RESETCONTENT:
  387.             strcpy (lsLBoxes[sLBoxNum].szPath, "");
  388.             strcpy (lsLBoxes[sLBoxNum].szSel, "");
  389.             lRetCode = 0;
  390.             break;
  391.     }
  392.     if (sLBoxNum >= sLBoxVStart && sLBoxNum < sLBoxVStart + sLBoxVisible)
  393.         return SendMessage (hwndLBoxArray[sLBoxNum - sLBoxVStart], 
  394.                             msg, wParam, lParam);
  395.    return lRetCode;
  396. }                            
  397.  
  398. //------------------------------------------------------------------------
  399. // Returns the selected text of a virtual list box.
  400. //------------------------------------------------------------------------
  401. void GetLBoxText (int sLBoxNum, char *spOutText) {
  402.  
  403.     int    i;
  404.  
  405.     if (sLBoxNum >= sLBoxVStart && sLBoxNum < sLBoxVStart + sLBoxVisible) {
  406.  
  407.         i = sLBoxNum - sLBoxVStart;
  408.  
  409.           SendMessage (hwndLBoxArray [i], LB_GETTEXT,
  410.             (WORD) SendMessage (hwndLBoxArray [i], LB_GETCURSEL, 0, 0L), 
  411.             STRTOLP (lsLBoxes[sLBoxNum].szSel));
  412.     } 
  413.     strcpy (spOutText, lsLBoxes[sLBoxNum].szSel);
  414.     return;
  415. }
  416.  
  417. //------------------------------------------------------------------------
  418. // Scroll virtual list boxes
  419. //------------------------------------------------------------------------
  420. void ScrollLBoxes (int sScrollCnt) {
  421.  
  422.     int    i;
  423.  
  424.     i = min (GetDirDepth (), LBOXMAX);
  425.     sLBoxVStart = max (0, sLBoxVStart + sScrollCnt);
  426.     sLBoxVStart = min (sLBoxVStart, max (0, i - sLBoxVisible));
  427.     return;
  428. }
  429.  
  430. //------------------------------------------------------------------------
  431. // Translate a ListBox notification ID into a virtual LB ID
  432. //------------------------------------------------------------------------
  433. int TranslateID (WORD wParam) {
  434.     return wParam + sLBoxVStart;
  435. }
  436.  
  437. //========================================================================
  438. //
  439. // Listbox Data routines
  440. //
  441. //========================================================================
  442. //------------------------------------------------------------------------
  443. // Routine to fill a list box with a list of files
  444. //------------------------------------------------------------------------
  445. void FillListBox (HWND hwnd, char *szPath, int sBoxNum) {
  446.     char    szTemp [128];
  447.     int    sSort1, sSort2;
  448.     LONG    lRetCode;
  449.  
  450.     sSort1 = 0xA010;                                //Directory search
  451.     sSort2 = 0x2001 | sSearchFlags;            //File search
  452.  
  453.     if (!bDirFirst) {
  454.         sSort2 = sSort1;
  455.         sSort1 = 0x2001;
  456.     }
  457.     SendLBoxMsg (sBoxNum, WM_SETREDRAW, FALSE, 0L);
  458.  
  459.     strcpy (szTemp, szPath);
  460.     strcat (szTemp, "*.*");
  461.     SendLBoxMsg (sBoxNum, LB_DIR, sSort1, STRTOLP (szTemp));
  462.     SendLBoxMsg (sBoxNum, WM_SETREDRAW, TRUE, 0L);    
  463.     strcpy (szTemp, szPath);
  464.     strcat (szTemp, "*.*");
  465.     SendLBoxMsg (sBoxNum, LB_DIR, sSort2, STRTOLP (szTemp));
  466.  
  467.     lRetCode = SendLBoxMsg (sBoxNum, LB_FINDSTRING, -1, STRTOLP ("[..]")); 
  468.     if (lRetCode != LB_ERR)
  469.         SendLBoxMsg (sBoxNum, LB_DELETESTRING, (WORD) lRetCode, 0L); 
  470.  
  471.    return;
  472. }
  473.  
  474. //------------------------------------------------------------------------
  475. // Routine to fill the list boxes using the default path
  476. //------------------------------------------------------------------------
  477. int ParsePath (HWND hwnd, int sBoxNum, char *szPath, int sPtr) {
  478.  
  479.    char     chr, szDir [15];
  480.     int    i;
  481.  
  482.     chr = szPath [sPtr+1];
  483.     szPath [sPtr+1] = 0;
  484.     FillListBox (hwnd, szPath, sBoxNum);
  485.     szPath [sPtr+1] = chr;
  486.     strcpy (szDir, "[");
  487.  
  488.     for (i = 1; i < 12 && szPath[sPtr+i] && szPath[sPtr+i] != '\\'; i++) 
  489.        szDir [i] = szPath [sPtr+i];
  490.  
  491.     szDir [i] = 0;
  492.     strcat (szDir, "]");
  493.  
  494.     SendLBoxMsg (sBoxNum, LB_SELECTSTRING, -1, STRTOLP (szDir));
  495.  
  496.     if (szPath [sPtr+i] && sBoxNum < sLBoxCount)
  497.         ParsePath (hwnd, sBoxNum+1, szPath, sPtr+i);
  498.     else {
  499.         strcat (szPath , "\\");
  500.         FillListBox (hwnd, szPath, sBoxNum+1);
  501.     }
  502.    return 1;
  503. }
  504.  
  505. //------------------------------------------------------------------------
  506. // Routine to fill all list boxes
  507. //------------------------------------------------------------------------
  508. int GetDirDepth () {
  509.     char    szPath [128];
  510.     int    i, j, sPathLen;
  511.  
  512.    getcwd (szPath, sizeof (szPath));
  513.     //    
  514.     // Count the depth of the current directory by counting '\' chars.
  515.     //
  516.     sPathLen = strlen (szPath);
  517.     j = 1;
  518.     if (sPathLen != 3)
  519.         for (i = 0; i < sPathLen; i++)
  520.             if (szPath[i] == '\\')
  521.                 j++;
  522.    return j;
  523. }
  524.  
  525. //------------------------------------------------------------------------
  526. // Routine to fill all list boxes
  527. //------------------------------------------------------------------------
  528. void RefreshListBoxes (HWND hwnd) {
  529.     char    szPath [128], szTemp[10];
  530.     int    i;
  531.  
  532.     for (i = 0; i < sLBoxCount; i++)
  533.         SendLBoxMsg (i, LB_RESETCONTENT, 0, 0L);
  534.  
  535.     getcwd (szPath, sizeof (szPath));
  536.     strcpy (szMasterPath, szPath);
  537.  
  538.     SetWindowText (hwndEditBox, szPath);
  539.     bDir = TRUE;
  540.     bExecutable = FALSE;
  541.     EnableButtons (hwnd, bExecutable, bDir);
  542.  
  543.     strcpy (szTemp, "[---]");
  544.     szTemp [2] = szPath [0] + (char) 0x20;
  545.     SendMessage (hwndDrvBox, LB_SELECTSTRING, -1, STRTOLP (szTemp));
  546.  
  547.     SetScrollPos (hwndScrollBar, SB_CTL, sLBoxVStart, TRUE);
  548.  
  549.     ParsePath (hwnd, 0, szPath, 2);
  550.  
  551.     return;
  552. }
  553.  
  554. //------------------------------------------------------------------------
  555. // Routine to fill all list boxes. 
  556. // Returns the ID of the last list box filled.
  557. //------------------------------------------------------------------------
  558. int FillListBoxes (HWND hwnd) {
  559.     int    sDDepth;
  560.  
  561.     sDDepth = GetDirDepth ();
  562.     //
  563.     // If directory deeper than number of listboxes, shift starting dir
  564.     //    
  565.     if (sDDepth <= sLBoxVisible) {
  566.         if (sLBoxVStart > 0) 
  567.             ScrollLBoxes (-sLBoxVStart);
  568.         SetScrollRange (hwndScrollBar, SB_CTL, 0, 0, FALSE);
  569.     } else {
  570.         ScrollLBoxes (sDDepth - sLBoxVStart - sLBoxVisible);
  571.         SetScrollRange (hwndScrollBar, SB_CTL, 0, sLBoxVStart, FALSE);
  572.     }
  573.     RefreshListBoxes (hwnd);
  574.    return min (sDDepth, sLBoxVisible) - 1;
  575. }
  576.  
  577. //========================================================================
  578. //
  579. // Functional support routines
  580. //
  581. //========================================================================
  582.  
  583. //------------------------------------------------------------------------
  584. // Routine to determine a file is executable.
  585. //------------------------------------------------------------------------
  586. BOOL IsProgram (char *szPrograms, char *szInPath) {
  587.  
  588.       char    szDrive [4], szDir [64], szName [12], szExt[8];
  589.  
  590.     _splitpath (szInPath, szDrive, szDir, szName, szExt);
  591.  
  592.     if (strlen (szExt) > 1) {
  593.         strcat (szExt, " ");
  594.         if (strstr (szPrograms, szExt+1))
  595.             return TRUE;
  596.     }
  597.       return FALSE;
  598. }
  599.  
  600. //------------------------------------------------------------------------
  601. // Enable/Disable Menu items and Buttons.
  602. //------------------------------------------------------------------------
  603. BOOL EnableButtons (HWND hwnd, BOOL bProgram, BOOL bDir) {
  604.  
  605.     int    i;
  606.  
  607.     for (i = 0; i < sButtonCount; i++) {
  608.  
  609.         if (bsButtons[i].sFunction == 0) {
  610.             if (bDir) {
  611.                 EnableWindow (bsButtons[i].hwndButton, FALSE);
  612.                 EnableMenuItem (GetMenu (hwnd), IDM_OPEN, 
  613.                                 MF_GRAYED);
  614.             } else {
  615.                 EnableWindow (bsButtons[i].hwndButton, TRUE);
  616.                 EnableMenuItem (GetMenu (hwnd), IDM_OPEN, 
  617.                                 MF_ENABLED);
  618.             }
  619.         } else 
  620.             EnableWindow (bsButtons[i].hwndButton, TRUE);
  621.     }
  622.     return bProgram;    
  623. }
  624.  
  625. //------------------------------------------------------------------------
  626. // Get Disk Bytes Free
  627. //------------------------------------------------------------------------
  628. LONG GetDiskFree (int sDiskNum) {
  629.  
  630.     DISKFREE_T    dfData;
  631.     int            rc;
  632.     LONG            lBytesFree;
  633.  
  634.     rc = _dos_getdiskfree (sDiskNum, &dfData);
  635.     if (rc)
  636.         return -1;
  637.     else {
  638.         lBytesFree = (LONG) dfData.avail_clusters;        
  639.         lBytesFree *= (LONG) dfData.sectors_per_cluster;
  640.         lBytesFree *= (LONG) dfData.bytes_per_sector;
  641.         return lBytesFree;
  642.     }
  643. }
  644.  
  645. //------------------------------------------------------------------------
  646. // Get File Info
  647. //------------------------------------------------------------------------
  648. int GetFileInfo (char *szFileName, FILEINFO *pfiData) {
  649.  
  650.     FIND_T    fs;
  651.     int    rc, sFlags = _A_ARCH | _A_NORMAL | _A_HIDDEN | _A_RDONLY | 
  652.                      _A_SYSTEM | _A_SUBDIR;
  653.  
  654.     //
  655.     // If Root dir, look for Volume ID. If not found, fake.
  656.     //
  657.     if (strlen (szFileName) == 3) {
  658.         strcat (szFileName, "*.*");
  659.         rc = _dos_findfirst (szFileName, _A_VOLID, &fs);
  660.         szFileName[4] = '\0';        
  661.         if (rc == 0x12) {
  662.             strcpy (fs.name, "Drive A");
  663.             fs.name[6] = szFileName[0];
  664.             fs.size = GetDiskFree (szFileName[0] - '@');
  665.             fs.wr_date = 1;
  666.             fs.wr_time = 0;
  667.             fs.attrib = _A_VOLID;
  668.             rc = 0;
  669.         }
  670.     } else
  671.         rc = _dos_findfirst (szFileName, sFlags, &fs);
  672.  
  673.     pfiData->lSize = fs.size;
  674.     pfiData->wDate = fs.wr_date;
  675.     pfiData->wTime = fs.wr_time;
  676.     pfiData->wAttr = fs.attrib;
  677.     strcpy (pfiData->szName, fs.name);
  678.     
  679.     return rc; 
  680. }
  681.  
  682. //------------------------------------------------------------------------
  683. // Convert date
  684. //------------------------------------------------------------------------
  685. void ConvertDate (WORD wDate, char *szBuffer) {
  686.  
  687.     int    i;
  688.     char    szTemp [20];
  689.     static    char szMonth[12][10] = {"January",
  690.                                          "February",
  691.                                          "March",
  692.                                          "April",
  693.                                          "May",
  694.                                          "June",
  695.                                          "July",
  696.                                          "August",
  697.                                          "September",
  698.                                          "October",
  699.                                          "November",
  700.                                          "December"};
  701.  
  702.     i = wDate;                        //Month
  703.     i >>= 5;
  704.     i &= 0x000F;
  705.     i = max (1, min (i, 12));
  706.     strcpy (szBuffer, szMonth[i-1]);
  707.     strcat (szBuffer, " ");
  708.  
  709.     i = wDate;                        //Day
  710.     i &= 0x001F;
  711.     itoa (i, szTemp, 10);
  712.     strcat (szBuffer, szTemp);
  713.     strcat (szBuffer, ",");
  714.  
  715.     wDate >>= 9;                      //Year
  716.     wDate &= 0x007F;
  717.     wDate += 1980;
  718.     itoa (wDate, szTemp, 10);
  719.     strcat (szBuffer, szTemp);
  720.  
  721.     return;
  722. }
  723.  
  724. //------------------------------------------------------------------------
  725. // Convert time
  726. //------------------------------------------------------------------------
  727. void ConvertTime (WORD wTime, char *szBuffer) {
  728.  
  729.     int    i;
  730.     char    szTemp [20], szNoon[5];
  731.  
  732.  
  733.     i = wTime;                           // Hours
  734.     i >>= 11;
  735.     i &= 0x001F;
  736.     if (i > 12) {
  737.         i -= 12;
  738.         strcpy (szNoon, "  PM");
  739.     } else
  740.         strcpy (szNoon, "  AM");
  741.     if (i == 0) i = 12;
  742.     itoa (i, szTemp, 10);
  743.     strcpy (szBuffer, szTemp);
  744.     strcat (szBuffer, " : ");
  745.  
  746.     i = wTime;                          //Minutes
  747.     i &= 0x07E0;
  748.     i >>= 5;
  749.     itoa (i, szTemp, 10);
  750.     if (strlen (szTemp) == 1)
  751.         strcat (szBuffer, "0");
  752.     strcat (szBuffer, szTemp);
  753.  
  754.     strcat (szBuffer, szNoon);
  755.  
  756.     return;
  757. }
  758.  
  759. //------------------------------------------------------------------------
  760. // Get File Type
  761. //------------------------------------------------------------------------
  762. void GetFileType (char *szFileName, WORD wFlags, char *szFileType, 
  763.                   char *szFileInfo) {
  764.  
  765.     char    szDrive[3], szDir[64], szName[9], szExt[5];
  766.  
  767.     _splitpath (szFileName, szDrive, szDir, szName, szExt);
  768.  
  769.     if (wFlags & _A_VOLID) {
  770.         strcpy (szFileType, "Drive");
  771.         return;
  772.     }
  773.     if (wFlags & _A_SUBDIR) {
  774.         strcpy (szFileType, "Directory");
  775.         return;
  776.     }
  777.     strupr (szExt);
  778.     //
  779.     // Check for standard COM file
  780.     //
  781.     if (strcmp (szExt, ".COM") == 0) {
  782.         strcpy (szFileType, "DOS Program");
  783.         strcpy (szFileInfo, "");
  784.     }
  785.     //
  786.     // Check for EXE file
  787.     //
  788.     else if (strcmp (szExt, ".EXE")==0) {
  789.         strcpy (szFileType, "DOS Program");
  790.         strcpy (szFileInfo, "");            
  791.     }
  792.     //
  793.     // Check for Bitmap file
  794.     //
  795.     else if (strcmp (szExt, ".BMP") == 0) {
  796.         strcpy (szFileType, "Bitmap");
  797.         strcpy (szFileInfo, "");
  798.     }
  799.     else
  800.         strcpy (szFileType, "File");
  801.  
  802.     return;
  803. }
  804.  
  805. //------------------------------------------------------------------------
  806. // Get DOS extended error info
  807. //------------------------------------------------------------------------
  808. int GetErrorCode () {
  809.     int        rc;
  810.     DOSERR    doserr;
  811.      
  812.     return rc = dosexterr (&doserr);
  813. }
  814.  
  815. //------------------------------------------------------------------------
  816. // Print DOS error code
  817. //------------------------------------------------------------------------
  818. void PrintError (HWND hwnd, int ErrorCode, char *szFileName) {
  819.     char        szTemp [64], szTemp1[128];
  820.  
  821.     //
  822.     // If fail on critical error, don't put up another box.    
  823.     if (ErrorCode == 53)
  824.         return;
  825.  
  826.     if (LoadString (hInstance, ErrorCode+200, szTemp, sizeof (szTemp)))
  827.         sprintf (szTemp1, szTemp, szFileName);
  828.     else
  829.         sprintf (szTemp1, "DOS Error %x", ErrorCode);
  830.     MessageBox (hwnd, szTemp1, szAppName, MB_OK);
  831. }
  832.  
  833. //========================================================================
  834. //
  835. // Function procedures
  836. //
  837. //========================================================================
  838. //------------------------------------------------------------------------
  839. // Create a directory
  840. //------------------------------------------------------------------------
  841. BOOL    MakeDir (char *szNewDir) {
  842.  
  843.    if (mkdir (szNewDir))
  844.         return FALSE;
  845.     else
  846.         return TRUE;
  847. }
  848.  
  849. //------------------------------------------------------------------------
  850. // Copy a file
  851. //------------------------------------------------------------------------
  852. BOOL    CopyFile (HWND hwnd, char *szDestFile, char *szSrcFile) {
  853.  
  854.     char        szTempDest[128];
  855.     int        rc, hSrc, hDest, i;
  856.     WORD        wByteCount, wBuffSize;        
  857.     DWORD        lBytesRead, lBytesFree;
  858.     HANDLE    hMem;
  859.     OFSTRUCT    ofFile;
  860.     LPSTR        lpBuffer;
  861.     FILEINFO    fiData;
  862.     
  863.     //
  864.     // See if destination disk valid
  865.     //
  866.     if (rc = GetFileInfo (szSrcFile, &fiData)) {
  867.         PrintError (hwnd, rc, szSrcFile);
  868.         return FALSE;
  869.     } 
  870.     strcpy (szTempDest, szDestFile);
  871.     //
  872.     // See if room on destination disk 
  873.     //
  874.     lBytesFree = GetDiskFree (szTempDest[0] - '@');
  875.     if (lBytesFree == -1) {
  876.         rc = GetErrorCode ();
  877.         return FALSE;
  878.     }
  879.     if (fiData.lSize > lBytesFree) {
  880.         PrintError (hwnd, 0, "");
  881.         return 0;
  882.     }    
  883.     //
  884.     // Open Source file
  885.     //    
  886.     hSrc = OpenFile (szSrcFile, &ofFile, OF_READ);
  887.     if (hSrc == -1) {
  888.         PrintError (hwnd, ofFile.nErrCode, szSrcFile);
  889.         return FALSE;
  890.     }
  891.     //
  892.     // Open Destination file, first, append src filename.
  893.     //    
  894.     i = strlen (szTempDest);
  895.     if (szTempDest[i-1] != '\\')
  896.         strcat (szTempDest, strrchr (szSrcFile, '\\'));
  897.     else
  898.          strcat (szTempDest, strrchr (szSrcFile, '\\')+1);
  899.  
  900.     hDest = OpenFile (szTempDest, &ofFile, OF_CREATE);
  901.     if (hDest == -1) {
  902.         //
  903.         // If path not found error, delete src filename
  904.         //
  905.         if (ofFile.nErrCode == 3) {
  906.             szTempDest[i] ='\0';
  907.             hDest = OpenFile (szTempDest, &ofFile, OF_CREATE);
  908.         }
  909.         if (hDest == -1) {
  910.             PrintError (hwnd, ofFile.nErrCode, szTempDest);
  911.             _lclose (hSrc);
  912.             return FALSE;
  913.         } 
  914.     }
  915.     //
  916.     // Allocate memory for a copy buffer
  917.     //    
  918.     if (fiData.lSize > 0xC000)
  919.         wBuffSize = 0xC000;
  920.     else    
  921.         wBuffSize = (WORD) fiData.lSize;
  922.     hMem = GlobalAlloc (GMEM_DISCARDABLE | GMEM_MOVEABLE, (DWORD) wBuffSize);
  923.     if (!hMem) {
  924.         PrintError (hwnd, 8, "");
  925.         _lclose (hSrc);
  926.         _lclose (hDest);
  927.         return FALSE;
  928.     }
  929.     //
  930.     // Copy loop
  931.     //    
  932.     rc = 0;
  933.     lBytesRead = 0;
  934.     while (lBytesRead < fiData.lSize && rc == 0) {
  935.         //
  936.         // Lock memory block. If discarded, reallocate.
  937.         //
  938.         lpBuffer = GlobalLock (hMem);
  939.         if (!lpBuffer) {
  940.             hMem = GlobalReAlloc (hMem, (DWORD) wBuffSize, 
  941.                                   GMEM_DISCARDABLE | GMEM_MOVEABLE);
  942.             if (!hMem) {
  943.                 _lclose (hSrc);
  944.                 _lclose (hDest);
  945.                 PrintError (hwnd, 8, "");
  946.                 return FALSE;
  947.             }
  948.             lpBuffer = GlobalLock (hMem);
  949.             if (!lpBuffer) {
  950.                 _lclose (hSrc);
  951.                 _lclose (hDest);
  952.                 PrintError (hwnd, 8, "");
  953.                 return FALSE;
  954.             }
  955.         }
  956.         wByteCount = _lread (hSrc, lpBuffer, wBuffSize);
  957.         if (wByteCount == 0xFFFF)
  958.             rc = GetErrorCode ();
  959.         else {
  960.             lBytesRead += wByteCount;
  961.             wByteCount = _lwrite (hDest, lpBuffer, wByteCount);
  962.             if (wByteCount == 0xFFFF)
  963.                 rc = GetErrorCode ();
  964.         }
  965.         GlobalUnlock (hMem);
  966.     }
  967.     //
  968.     // Clean up
  969.     //    
  970.     GlobalFree (hMem);
  971.     _lclose (hSrc);
  972.     _lclose (hDest);
  973.  
  974.     if (rc) {
  975.         PrintError (hwnd, rc, "");
  976.         return FALSE;
  977.     } else
  978.         return TRUE;
  979. }
  980.  
  981. //------------------------------------------------------------------------
  982. // Copy directory
  983. //------------------------------------------------------------------------
  984. BOOL    CopyDir (HWND hwnd, char *szDestDir, char *szSrcDir, BOOL bRecurse) {
  985.  
  986.     FIND_T    fs;
  987.     int        rc, sFlags = _A_ARCH | _A_SUBDIR;
  988.  
  989.     rc = _dos_findfirst (szDestDir, sFlags | _A_HIDDEN | _A_SYSTEM, &fs);
  990.     if (rc)
  991.         if (!MakeDir (szDestDir)) {
  992.             PrintError (hwnd, GetErrorCode(), szDestDir);
  993.             return FALSE;
  994.         }
  995.  
  996.     strcat (szSrcDir, "\\*.*");
  997.     rc = _dos_findfirst (szSrcDir, sFlags | sSearchFlags, &fs);
  998.     *strrchr (szSrcDir, '\\') = '\0';
  999.  
  1000.     while (rc == 0) {
  1001.         strcat (szSrcDir, "\\"); 
  1002.         strcat (szSrcDir, fs.name);
  1003.  
  1004.         if (fs.attrib & _A_SUBDIR) {
  1005.             if (bRecurse && strcmp (fs.name, ".") != 0 
  1006.                          && strcmp (fs.name, "..") != 0) {
  1007.                 strcat (szDestDir, "\\");
  1008.                 strcat (szDestDir, fs.name);
  1009.                 if (!CopyDir (hwnd, szDestDir, szSrcDir, 
  1010.                               bRecurse))
  1011.                     rc = 1;
  1012.                 *strrchr (szDestDir, '\\') = '\0';
  1013.             }
  1014.         } else
  1015.              if (!CopyFile(hwnd, szDestDir, szSrcDir))
  1016.                 rc = 1;
  1017.         *strrchr (szSrcDir, '\\') = '\0';
  1018.  
  1019.         if (!rc)
  1020.             rc = _dos_findnext (&fs);
  1021.     }
  1022.     if (rc != 0x12) {
  1023.         PrintError (hwnd, GetErrorCode(), szSrcDir);
  1024.         return FALSE;
  1025.     }
  1026.     return TRUE;
  1027. }
  1028. //------------------------------------------------------------------------
  1029. // Delete a file
  1030. //------------------------------------------------------------------------
  1031. BOOL    DeleteFile (HWND hwnd, char *szFile) {
  1032.  
  1033.     OFSTRUCT    ofFileData;
  1034.  
  1035.     OpenFile (szFile, &ofFileData, OF_EXIST | OF_DELETE);
  1036.     
  1037.     if (ofFileData.nErrCode && ofFileData.nErrCode != 2) {
  1038.         PrintError (hwnd, ofFileData.nErrCode, szFile);
  1039.         return FALSE;
  1040.     } 
  1041.     return TRUE;
  1042. }
  1043.  
  1044. //------------------------------------------------------------------------
  1045. // Delete directories
  1046. //------------------------------------------------------------------------
  1047. BOOL    DeleteDir (HWND hwnd, char *szDir, BOOL bRecurse) {
  1048.  
  1049.     FIND_T    fs;
  1050.     int        rc, sFlags = _A_ARCH | _A_SUBDIR;
  1051.  
  1052.     strcat (szDir, "\\*.*");
  1053.     rc = _dos_findfirst (szDir, sFlags | sSearchFlags, &fs);
  1054.     *strrchr (szDir, '\\') = '\0';
  1055.  
  1056.     while (rc == 0) {
  1057.         strcat (szDir, "\\"); 
  1058.         strcat (szDir, fs.name);
  1059.  
  1060.         if (fs.attrib & _A_SUBDIR) {
  1061.             if (bRecurse && strcmp (fs.name, ".") != 0 
  1062.                          && strcmp (fs.name, "..") != 0) 
  1063.                 if (!DeleteDir (hwnd, szDir, bRecurse))
  1064.                     rc = 1;
  1065.         } else
  1066.              if (!DeleteFile(hwnd, szDir))
  1067.                 rc = 1;
  1068.         *strrchr (szDir, '\\') = '\0';
  1069.  
  1070.         if (!rc)
  1071.             rc = _dos_findnext (&fs);
  1072.     }
  1073.     if (rc != 0x12) {
  1074.         PrintError (hwnd, GetErrorCode(), szDir);
  1075.         return FALSE;
  1076.     }
  1077.     if (strlen (szDir) != 3) {        
  1078.         if (rmdir (szDir)) {
  1079.             rc = GetErrorCode();
  1080.             if (rc == 16 || rc == 5) {
  1081.                 char    szTemp[128];
  1082.                 strcpy (szTemp, szDir);
  1083.                 *strrchr (szTemp, '\\') = '\0';
  1084.                 if (strlen (szTemp) == 2) strcat (szTemp, "\\");
  1085.                 chdir (szTemp);
  1086.                 rc = 0;
  1087.                 if (rmdir (szDir)) rc = GetErrorCode();
  1088.             }
  1089.             if (rc) {
  1090.                 PrintError (hwnd, GetErrorCode(), szDir);
  1091.                 return FALSE;
  1092.             }
  1093.         }
  1094.     }
  1095.     return TRUE;
  1096. }
  1097.  
  1098. //========================================================================
  1099. //
  1100. // Control Subclass Procedures
  1101. //
  1102. //========================================================================
  1103. //------------------------------------------------------------------------
  1104. //
  1105. // Listbox subclass procedure
  1106. //
  1107. //------------------------------------------------------------------------
  1108. long FAR PASCAL ListBoxSubclassProc (HWND hwnd, WORD message, WORD wParam, 
  1109.                                      LONG lParam) {
  1110. int    sLBoxID;
  1111. sLBoxID = GetWindowWord (hwnd, GWW_ID);
  1112. switch (message) {
  1113.  
  1114.     case WM_SETFOCUS:
  1115.         hwndFocusWin = hwnd;
  1116.         break;
  1117.  
  1118.     case WM_KEYDOWN:
  1119.         switch (wParam) {
  1120.  
  1121.             case VK_RETURN:
  1122.                 SendMessage (GetParent (hwnd), WM_COMMAND, 
  1123.                              sLBoxID,
  1124.                              MAKELONG (hwnd, LBN_DBLCLK));
  1125.                 break;
  1126.  
  1127.             case VK_TAB:
  1128.  
  1129.                 if (sLBoxID == IDD_DRVBOX) {
  1130.                     if (GetKeyState (VK_SHIFT) < 0)
  1131.                         SetFocus (hwndEditBox);
  1132.                     else
  1133.                         SetFocus (hwndLBoxArray[0]);
  1134.                 } else                            
  1135.                     if (GetKeyState (VK_SHIFT) < 0) {
  1136.                         if (sLBoxID == IDD_1STBOX)
  1137.                             SetFocus (hwndDrvBox);
  1138.                         else 
  1139.                             SetFocus(hwndLBoxArray[sLBoxID-IDD_1STBOX-1]);
  1140.                     } else {
  1141.                         if (sLBoxID == IDD_1STBOX + sLBoxVisible - 1)
  1142.                             SetFocus (hwndEditBox);
  1143.                         else 
  1144.                             SetFocus(hwndLBoxArray[sLBoxID-IDD_1STBOX+1]);
  1145.                     }
  1146.                 break;
  1147.         }
  1148.         break;
  1149. }
  1150. return CallWindowProc (lpfnOldLBoxProc[sLBoxID-IDD_DRVBOX], hwnd, 
  1151.                        message, wParam, lParam);
  1152. }
  1153.  
  1154. //------------------------------------------------------------------------
  1155. //
  1156. // Editbox subclass procedure
  1157. //
  1158. //------------------------------------------------------------------------
  1159. long FAR PASCAL EditBoxSubclassProc (HWND hwnd, WORD message, WORD wParam, 
  1160.                                      LONG lParam) {
  1161.  
  1162.     switch (message) {
  1163.  
  1164.         case WM_SETFOCUS:
  1165.             hwndFocusWin = hwnd;
  1166.             break;
  1167.  
  1168.         case WM_KEYDOWN:
  1169.             switch (wParam) {
  1170.  
  1171.                 case VK_RETURN:
  1172.                     SendMessage (GetParent (hwnd), 
  1173.                                  WUM_SETPATH, 0, 0);
  1174.                     return 0;
  1175.  
  1176.                 case VK_TAB:
  1177.  
  1178.                     if (GetKeyState (VK_SHIFT) < 0)
  1179.                         SetFocus (hwndLBoxArray[sLBoxVisible-1]);
  1180.                     else
  1181.                         SetFocus (hwndDrvBox);
  1182.                     return 0;
  1183.             }
  1184.             break;
  1185.         case WM_CHAR:
  1186.             switch (wParam) {
  1187.  
  1188.                 case '\t':
  1189.                     return 0;
  1190.  
  1191.                 case '\r':
  1192.                     return 0;
  1193.             }
  1194.             break;
  1195.     }
  1196.     return CallWindowProc (lpfnOldEditBoxProc, hwnd, message, 
  1197.                            wParam, lParam);
  1198. }
  1199.  
  1200.  
  1201. //========================================================================
  1202. //
  1203. // Window Proceedures for Dialog Boxes
  1204. //
  1205. //========================================================================
  1206. //------------------------------------------------------------------------
  1207. //
  1208. //Configure Dialog procedure
  1209. //
  1210. //------------------------------------------------------------------------
  1211. BOOL FAR PASCAL ConfigDlgProc (HWND hwnd, WORD message, WORD wParam, 
  1212.                                LONG lParam) {
  1213.  
  1214. static    int    sLocalButtons [BUTTONMAX], sLocalTotal;
  1215. int        i;
  1216. char         szTemp [128], szTemp1[8];
  1217. BOOL        bGood;
  1218.  
  1219. switch (message) {
  1220.     case WM_INITDIALOG:
  1221.  
  1222.         for (i = 0; i < BUTTONMAX; i++) 
  1223.             sLocalButtons[i] = bsButtons[i].sFunction;
  1224.         sLocalTotal = sButtonCount;
  1225.             
  1226.         SendDlgItemMessage (hwnd, IDD_EDITORNAME, EM_LIMITTEXT, 
  1227.                             sizeof (szDefaultEditor), 0L);    
  1228.         SetDlgItemText (hwnd, IDD_EDITORNAME, szDefaultEditor);
  1229.  
  1230.         if (sSearchFlags && 0x0002)
  1231.             CheckDlgButton (hwnd, IDD_INCHIDDEN, TRUE);
  1232.         else
  1233.             CheckDlgButton (hwnd, IDD_INCHIDDEN, FALSE);
  1234.         if (sSearchFlags && 0x0004)
  1235.             CheckDlgButton (hwnd, IDD_INCSYSTEM, TRUE);
  1236.         else
  1237.             CheckDlgButton (hwnd, IDD_INCSYSTEM, FALSE);
  1238.  
  1239.         if (bDirFirst)
  1240.             CheckRadioButton (hwnd, IDD_SRTDIR1ST, 
  1241.                             IDD_SRTDIRLST, IDD_SRTDIR1ST);
  1242.         else
  1243.             CheckRadioButton (hwnd, IDD_SRTDIR1ST, 
  1244.                             IDD_SRTDIRLST, IDD_SRTDIRLST);
  1245.  
  1246.         CheckDlgButton (hwnd, IDD_CONFFDEL, bConfirmFileDel);
  1247.         CheckDlgButton (hwnd, IDD_CONFDDEL, bConfirmDirDel);
  1248.  
  1249.         SendDlgItemMessage (hwnd, IDD_BTNTOTAL, 
  1250.                             EM_LIMITTEXT, 2, 0L);
  1251.         SetDlgItemInt (hwnd, IDD_BTNTOTAL, sButtonCount, 
  1252.                        FALSE);
  1253.         SendDlgItemMessage (hwnd, IDD_BTNNUM, 
  1254.                             EM_LIMITTEXT, 2, 0L);
  1255.         SetDlgItemInt (hwnd, IDD_BTNNUM, 1, FALSE);
  1256.         SendDlgItemMessage (hwnd, IDD_BTNNUM, 
  1257.                             CB_RESETCONTENT, 0, 0L);
  1258.         for (i = 0; i < 10; i++) {
  1259.             itoa (i+1, szTemp1, 10);
  1260.             strcpy (szTemp, "Button ");
  1261.             strcat (szTemp, szTemp1);
  1262.             SendDlgItemMessage (hwnd, IDD_BTNNUM, 
  1263.                                 CB_ADDSTRING, 0,
  1264.                                 STRTOLP (szTemp));
  1265.         }
  1266.         SendDlgItemMessage (hwnd, IDD_BTNNUM, 
  1267.                             CB_SETCURSEL, 0, 0);
  1268.         SendDlgItemMessage (hwnd, IDD_BTNFUNC, 
  1269.                             CB_RESETCONTENT, 0, 0L);
  1270.         for (i = 0; i < 10; i++) 
  1271.             SendDlgItemMessage (hwnd, IDD_BTNFUNC, 
  1272.                           CB_ADDSTRING, 0, 
  1273.                           STRTOLP (fsFunctions[i].szText));
  1274.         SendDlgItemMessage (hwnd, IDD_BTNFUNC, CB_SETCURSEL, 
  1275.                             sLocalButtons[0], 0);
  1276.         return TRUE;
  1277.  
  1278.     case WM_COMMAND:
  1279.         switch (wParam) {
  1280.             case IDD_BTNTOTAL:
  1281.                 if (HIWORD (lParam) == EN_KILLFOCUS) {
  1282.                     i=GetDlgItemInt (hwnd, 
  1283.                             IDD_BTNTOTAL, &bGood, FALSE);
  1284.                     if (!bGood) 
  1285.                         SetDlgItemInt (hwnd, 
  1286.                             IDD_BTNTOTAL, 
  1287.                             sLocalTotal, FALSE);
  1288.                     else {
  1289.                         if (i<0 || i>BUTTONMAX) {
  1290.                             i = max (1, min (i, BUTTONMAX));
  1291.                             SetDlgItemInt (hwnd, IDD_BTNTOTAL, 
  1292.                                            sLocalTotal, FALSE);
  1293.                         }
  1294.                         sLocalTotal = i;
  1295.                     }
  1296.                 }
  1297.                 break;
  1298.  
  1299.             case IDD_BTNNUM:
  1300.                 if (HIWORD (lParam) == CBN_SELCHANGE) {
  1301.  
  1302.                     i = (int) SendDlgItemMessage(hwnd, IDD_BTNNUM, 
  1303.                                                  CB_GETCURSEL, 0, 0);
  1304.                     SendDlgItemMessage (hwnd, IDD_BTNFUNC, CB_SETCURSEL, 
  1305.                                         sLocalButtons[i], 0);
  1306.                 }
  1307.                 break;
  1308.  
  1309.             case IDD_BTNFUNC:
  1310.                 if (HIWORD (lParam) == CBN_SELCHANGE) {
  1311.                     i = (int) SendDlgItemMessage (hwnd, IDD_BTNNUM, 
  1312.                                                   CB_GETCURSEL, 0, 0L);
  1313.                     sLocalButtons[i] = (int) SendDlgItemMessage (hwnd, 
  1314.                                               IDD_BTNFUNC, CB_GETCURSEL, 
  1315.                                               0, 0L);
  1316.                 }
  1317.                 break;
  1318.  
  1319.             case IDD_SRTDIR1ST:
  1320.             case IDD_SRTDIRLST:
  1321.                 CheckRadioButton (hwnd, IDD_SRTDIR1ST, IDD_SRTDIRLST, 
  1322.                                   wParam);
  1323.                 break;
  1324.  
  1325.             case IDOK:
  1326.                 //
  1327.                 // Set include flags from check box settings
  1328.                 //
  1329.                 sSearchFlags &= 0xFFF9;
  1330.                 if (IsDlgButtonChecked (hwnd, IDD_INCHIDDEN) == 1)
  1331.                     sSearchFlags |= 0x0002;
  1332.                 if (IsDlgButtonChecked (hwnd, IDD_INCSYSTEM) == 1)
  1333.                     sSearchFlags |= 0x0004;
  1334.                 //
  1335.                 // Set Confirmation flags from check box settings
  1336.                 //
  1337.                 if (IsDlgButtonChecked (hwnd, IDD_CONFFDEL) == 1)
  1338.                     bConfirmFileDel = TRUE;
  1339.                 else
  1340.                     bConfirmFileDel = FALSE;
  1341.                 if (IsDlgButtonChecked (hwnd, IDD_CONFDDEL) == 1)
  1342.                     bConfirmDirDel = TRUE;
  1343.                 else
  1344.                     bConfirmDirDel = FALSE;
  1345.                 //
  1346.                 // Set Directory sort flag
  1347.                 //
  1348.                 if (IsDlgButtonChecked (hwnd, IDD_SRTDIR1ST) == 1)
  1349.                     bDirFirst = TRUE;
  1350.                 else
  1351.                     bDirFirst = FALSE;
  1352.                 //
  1353.                 // Assign new button count and functions. 
  1354.                 //
  1355.                 sButtonCount = GetDlgItemInt (hwnd, IDD_BTNTOTAL, 
  1356.                                               &bGood, FALSE);
  1357.  
  1358.                 for (i = 0; i < BUTTONMAX; i++) 
  1359.                     if (bsButtons[i].sFunction != sLocalButtons[i]) {
  1360.                         bsButtons[i].sFunction = sLocalButtons[i];
  1361.                         if (bsButtons[i].hwndButton != 0)
  1362.                             SetWindowText (bsButtons[i].hwndButton,
  1363.                              fsFunctions [bsButtons [i].sFunction].szText);
  1364.                     }
  1365.                 //
  1366.                 // Assign new default editor name.
  1367.                 //
  1368.                 GetDlgItemText (hwnd, IDD_EDITORNAME, szDefaultEditor,
  1369.                                 sizeof (szDefaultEditor));
  1370.                 EndDialog (hwnd, 1);
  1371.                 return TRUE;
  1372.  
  1373.             case IDCANCEL:    
  1374.                 EndDialog (hwnd, 0);
  1375.                 return TRUE;
  1376.         }
  1377.         break;
  1378.     case WM_CLOSE:
  1379.         EndDialog (hwnd, 0);
  1380.         return TRUE;
  1381. }
  1382. return FALSE;    
  1383. }
  1384.  
  1385. //------------------------------------------------------------------------
  1386. //
  1387. //Copy/Rename Dialog procedure
  1388. //
  1389. //------------------------------------------------------------------------
  1390. BOOL FAR PASCAL CopyRenDlgProc (HWND hwnd, WORD message, WORD wParam, 
  1391.                                LONG lParam) {
  1392. char    szTemp[80];
  1393. char    szSelect[16];
  1394. char    szSavePath[80];
  1395. int    i;
  1396.  
  1397. switch (message) {
  1398.  
  1399.     case WM_INITDIALOG:
  1400.  
  1401.         SendDlgItemMessage (hwnd, IDD_DESTNAME, EM_LIMITTEXT, 
  1402.                             sizeof (szTemp), 0L);    
  1403.  
  1404.         getcwd (szSavePath, sizeof (szSavePath));
  1405.         strcpy (szTemp, szMasterPath);
  1406.         if (!bDir) *strrchr (szTemp, '\\') = '\0';
  1407.         strcpy (szDestPath, szTemp);
  1408.         DlgDirList (hwnd, szDestPath, IDD_FDRVBOX, 0, 0xC000);
  1409.         strcpy (szDestPath, szTemp);
  1410.         DlgDirList (hwnd, szDestPath, IDD_FDIRBOX, 0, 0x8010);
  1411.         strcpy (szDestPath, szTemp);
  1412.         DlgDirList (hwnd, szDestPath, IDD_FFILEBOX, 0, 0x0007);
  1413.         SetDlgItemText (hwnd, IDD_DESTNAME, szTemp);
  1414.         strcpy (szTemp, szFunction);
  1415.         if (bDir)
  1416.             strcat (szTemp, " Directory:");
  1417.         else
  1418.             strcat (szTemp, " File:");
  1419.         SetDlgItemText (hwnd, IDD_FUNCNAME, szTemp);            
  1420.         SetDlgItemText (hwnd, IDD_SRCNAME, szMasterPath);
  1421.         if (strcmp (szFunction, "Rename") == 0) {
  1422.             CheckDlgButton (hwnd, IDD_SRCRECURSE, 2);
  1423.             ShowWindow (GetDlgItem (hwnd, IDD_SRCRECURSE), SW_HIDE);
  1424.         } else {
  1425.             ShowWindow (GetDlgItem (hwnd, IDD_SRCRECURSE), SW_SHOW);
  1426.             CheckDlgButton (hwnd, IDD_SRCRECURSE, 0);
  1427.         }
  1428.         return TRUE;
  1429.  
  1430.     case WM_COMMAND:
  1431.  
  1432.         if ((wParam == IDD_FDRVBOX || wParam == IDD_FDIRBOX ||
  1433.              wParam == IDD_FFILEBOX) && 
  1434.              (HIWORD (lParam) == LBN_DBLCLK ||
  1435.               HIWORD (lParam) == LBN_SELCHANGE)) {
  1436.  
  1437.             DlgDirSelect (hwnd, szSelect, wParam);
  1438.  
  1439.             switch (wParam) {
  1440.                 case IDD_FDRVBOX:
  1441.                     if (HIWORD (lParam) == LBN_DBLCLK) {
  1442.                         _chdrive (szSelect [0] - 'a' + 1);
  1443.                        getcwd (szTemp, sizeof (szTemp));
  1444.                     } else {
  1445.                         strcpy (szTemp, szSelect);
  1446.                         strcat (szTemp, "\\");
  1447.                     }
  1448.                     break;
  1449.  
  1450.                 case IDD_FDIRBOX:
  1451.  
  1452.                    getcwd (szTemp, sizeof (szTemp));
  1453.                     if (strcmp (szSelect, "..\\") == 0) {
  1454.                         *strrchr (szTemp, '\\') = '\0';
  1455.                         if (strlen (szTemp) == 2) strcat (szTemp, "\\");
  1456.                     } else {
  1457.                         if (strlen (szTemp) != 3) strcat (szTemp, "\\");
  1458.                         strcat (szTemp, szSelect);
  1459.                         *strrchr (szTemp, '\\') = '\0';
  1460.                     }    
  1461.                     if (HIWORD (lParam) == LBN_DBLCLK) 
  1462.                             chdir (szTemp);
  1463.                     break;    
  1464.  
  1465.                 case IDD_FFILEBOX:
  1466.                    getcwd (szTemp, sizeof (szTemp));
  1467.                     if (strlen (szTemp) != 3) strcat (szTemp, "\\");
  1468.                     strcat (szTemp, szSelect);
  1469.                     if (HIWORD (lParam) == LBN_DBLCLK) 
  1470.                         PostMessage (hwnd, WM_COMMAND, IDOK, 0L);
  1471.                     break;
  1472.             }
  1473.             if (HIWORD (lParam) == LBN_DBLCLK) {
  1474.                 strcpy (szDestPath, szTemp);
  1475.                 DlgDirList (hwnd, szDestPath, IDD_FDRVBOX, 0, 0xC000);
  1476.                 strcpy (szDestPath, szTemp);
  1477.                 DlgDirList (hwnd, szDestPath, IDD_FDIRBOX, 0, 0x8010);
  1478.                 strcpy (szDestPath, szTemp);
  1479.                 DlgDirList (hwnd, szDestPath, IDD_FFILEBOX, 0, 0x0007);
  1480.             }
  1481.             SetDlgItemText (hwnd, IDD_DESTNAME, szTemp);
  1482.         }
  1483.         switch (wParam) {
  1484.  
  1485.             case IDD_DESTNAME:
  1486.                 //
  1487.                 // Disable automatic text selection when gaining focus
  1488.                 //
  1489.                 if (HIWORD (lParam) == EN_SETFOCUS) {
  1490.                     GetDlgItemText (hwnd, IDD_DESTNAME, 
  1491.                                   szTemp, sizeof (szTemp));
  1492.                     i = strlen (szTemp);
  1493.                     SendMessage ((HWND) LOWORD (lParam), 
  1494.                                  EM_SETSEL, 0, 
  1495.                                  MAKELONG (i,i));
  1496.                 }
  1497.                 break;
  1498.             case IDOK:
  1499.                 //
  1500.                 // On OK, get destination filename text.  Compare it with
  1501.                 // the source filename.  If equal, reject dest name. If 
  1502.                 // dest name ok, get Inc Directories button state.
  1503.                 //
  1504.                 GetDlgItemText (hwnd, IDD_DESTNAME, szTemp, 
  1505.                                 sizeof (szTemp));
  1506.                 _fullpath (szDestPath, szTemp, 
  1507.                            sizeof (szDestPath));
  1508.                 if (strcmp (szMasterPath, szDestPath) == 0) {
  1509.                     MessageBox (hwnd,
  1510.                      "Source and Destination names cannot be the same", 
  1511.                                 szAppName, MB_OK);
  1512.                     break;
  1513.                 } 
  1514.                 if (IsDlgButtonChecked(hwnd,IDD_SRCRECURSE)==1)
  1515.                     bIncDir = TRUE;
  1516.                 else
  1517.                     bIncDir = FALSE;
  1518.                 chdir (szSavePath);
  1519.                 EndDialog (hwnd, 1);
  1520.                 return TRUE;
  1521.  
  1522.             case IDCANCEL:    
  1523.                 chdir (szSavePath);
  1524.                 EndDialog (hwnd, 0);
  1525.                 return TRUE;
  1526.         }
  1527.         break;
  1528.  
  1529.     case WM_CLOSE:
  1530.         EndDialog (hwnd, 0);
  1531.         return TRUE;
  1532. }
  1533. return FALSE;    
  1534. }
  1535.  
  1536. //------------------------------------------------------------------------
  1537. //
  1538. //Make Directory Dialog procedure
  1539. //
  1540. //------------------------------------------------------------------------
  1541. BOOL FAR PASCAL MkDirDlgProc (HWND hwnd, WORD message, WORD wParam, 
  1542.                                LONG lParam) {
  1543.     char    szTemp[80];
  1544.  
  1545.     switch (message) {
  1546.  
  1547.         case WM_INITDIALOG:
  1548.  
  1549.             SendDlgItemMessage (hwnd, IDD_DIRNAME, EM_LIMITTEXT, 
  1550.                                 sizeof (szTemp), 0L);    
  1551.  
  1552.             SetDlgItemText (hwnd, IDD_CURRDIR, szMasterPath);
  1553.  
  1554.             return TRUE;
  1555.  
  1556.         case WM_COMMAND:
  1557.  
  1558.             switch (wParam) {
  1559.  
  1560.                 case IDOK:
  1561.                     //
  1562.                     // On OK, get new directory name.
  1563.                     //
  1564.                     GetDlgItemText (hwnd, IDD_DIRNAME, 
  1565.                                     szTemp, 
  1566.                                     sizeof (szTemp));
  1567.                     _fullpath (szDestPath, szTemp, 
  1568.                                sizeof (szDestPath));
  1569.                     EndDialog (hwnd, 1);
  1570.                     return TRUE;
  1571.  
  1572.                 case IDCANCEL:    
  1573.                     EndDialog (hwnd, 0);
  1574.                     return TRUE;
  1575.             }
  1576.             break;
  1577.  
  1578.         case WM_CLOSE:
  1579.             EndDialog (hwnd, 0);
  1580.             return TRUE;
  1581.     }
  1582.     return FALSE;    
  1583. }
  1584.  
  1585. //------------------------------------------------------------------------
  1586. //
  1587. //Set File Attribute dialog procedure
  1588. //
  1589. //------------------------------------------------------------------------
  1590. BOOL FAR PASCAL SetAttrDlgProc (HWND hwnd, WORD message, WORD wParam, 
  1591.                                LONG lParam) {
  1592. static    int    sFileFlags;
  1593. char        szTemp[128];
  1594.  
  1595. switch (message) {
  1596.  
  1597.     case WM_INITDIALOG:
  1598.  
  1599.         SetDlgItemText (hwnd, IDD_SRCNAME, szMasterPath);
  1600.  
  1601.         strcpy (szTemp, "Set file attributes for ");
  1602.         if (bDir)
  1603.             strcat (szTemp, "Directory:");
  1604.         else
  1605.             strcat (szTemp, "File:");
  1606.         SetDlgItemText (hwnd, IDD_FUNCNAME, szTemp);            
  1607.  
  1608.         if (_dos_getfileattr (szMasterPath, &sFileFlags))
  1609.             return FALSE;
  1610.  
  1611.         if (sFileFlags & _A_HIDDEN)
  1612.             CheckDlgButton (hwnd, IDD_FILEHIDDEN, TRUE);
  1613.         else
  1614.             CheckDlgButton (hwnd, IDD_FILEHIDDEN, FALSE);
  1615.  
  1616.         if (sFileFlags & _A_SYSTEM)
  1617.             CheckDlgButton (hwnd, IDD_FILESYSTEM, TRUE);
  1618.         else
  1619.             CheckDlgButton (hwnd, IDD_FILESYSTEM, FALSE);
  1620.  
  1621.         if (sFileFlags & _A_RDONLY)
  1622.             CheckDlgButton (hwnd, IDD_FILEREADONLY, TRUE);
  1623.         else
  1624.             CheckDlgButton (hwnd, IDD_FILEREADONLY, FALSE);
  1625.  
  1626.         if (sFileFlags & _A_ARCH)
  1627.             CheckDlgButton (hwnd, IDD_FILEARCHIVE, TRUE);
  1628.         else
  1629.             CheckDlgButton (hwnd, IDD_FILEARCHIVE, FALSE);
  1630.  
  1631.         return TRUE;
  1632.  
  1633.     case WM_COMMAND:
  1634.  
  1635.         switch (wParam) {
  1636.  
  1637.             case IDOK:
  1638.  
  1639.                 //
  1640.                 // Set include flags from check box settings
  1641.                 //
  1642.                 
  1643.                 if (IsDlgButtonChecked (hwnd, IDD_FILEHIDDEN) == 1)
  1644.                     sFileFlags |= _A_HIDDEN;
  1645.                 else    
  1646.                     sFileFlags &= ~_A_HIDDEN;
  1647.  
  1648.                 if (IsDlgButtonChecked (hwnd, IDD_FILESYSTEM) == 1)
  1649.                     sFileFlags |= _A_SYSTEM;
  1650.                 else    
  1651.                     sFileFlags &= ~_A_SYSTEM;
  1652.  
  1653.                 if (IsDlgButtonChecked (hwnd, IDD_FILEREADONLY) == 1)
  1654.                     sFileFlags |= _A_RDONLY;
  1655.                 else    
  1656.                     sFileFlags &= ~_A_RDONLY;
  1657.  
  1658.                 if (IsDlgButtonChecked (hwnd, IDD_FILEARCHIVE) == 1)
  1659.                     sFileFlags |= _A_ARCH;
  1660.                 else    
  1661.                     sFileFlags &= ~_A_ARCH;
  1662.  
  1663.                 _dos_setfileattr (szMasterPath, sFileFlags);
  1664.                 EndDialog (hwnd, 1);
  1665.                 return TRUE;
  1666.  
  1667.             case IDCANCEL:    
  1668.                 EndDialog (hwnd, 0);
  1669.                 return TRUE;
  1670.         }
  1671.         break;
  1672.     case WM_CLOSE:
  1673.         EndDialog (hwnd, 0);
  1674.         return TRUE;
  1675. }
  1676. return FALSE;    
  1677. }
  1678.  
  1679. //------------------------------------------------------------------------
  1680. //
  1681. // File Infomation Dialog procedure
  1682. //
  1683. //------------------------------------------------------------------------
  1684. BOOL FAR PASCAL FileInfoDlgProc (HWND hwnd, WORD message, WORD wParam, 
  1685.                                  LONG lParam) {
  1686.     char        szTemp[128], szTemp1[32];
  1687.     FILEINFO    fiData;
  1688.     int        i, rc, sNumLen;
  1689.     int        sFlags = _A_ARCH | _A_NORMAL | _A_HIDDEN | 
  1690.                      _A_RDONLY | _A_SYSTEM | _A_SUBDIR;
  1691.  
  1692.     switch (message) {
  1693.  
  1694.         case WM_INITDIALOG:
  1695.  
  1696.             rc = GetFileInfo (szMasterPath, &fiData);
  1697.             if (rc) {
  1698.                 PrintError (hwnd, rc, szMasterPath);
  1699.                 return FALSE;
  1700.             }
  1701.             SetDlgItemText (hwnd, IDD_INFONAME, fiData.szName);
  1702.  
  1703.             GetFileType (szMasterPath, fiData.wAttr, szTemp1, 
  1704.                          szTemp);
  1705.             SetDlgItemText (hwnd, IDD_INFOTYPE, szTemp1);
  1706.             //
  1707.             // Insert commas in file size
  1708.             //
  1709.             ltoa (fiData.lSize, szTemp, 10);
  1710.             strcpy (szTemp1, "");
  1711.             sNumLen = strlen (szTemp);
  1712.  
  1713.             for (i = 0; i < sNumLen; i++) {
  1714.                 if ((sNumLen - i) % 3 == 0 && i != 0)
  1715.                     strcat (szTemp1, ",");
  1716.                 strncat (szTemp1, szTemp+i,1);
  1717.             }
  1718.             strcat (szTemp1, " Bytes");
  1719.             SetDlgItemText (hwnd, IDD_INFOSIZE, szTemp1);
  1720.  
  1721.             ConvertDate (fiData.wDate, szTemp);
  1722.             SetDlgItemText (hwnd, IDD_INFODATE, szTemp);
  1723.  
  1724.             ConvertTime (fiData.wTime, szTemp);
  1725.             SetDlgItemText (hwnd, IDD_INFOTIME, szTemp);
  1726.  
  1727.             strcpy (szTemp, "");
  1728.             if (fiData.wAttr & _A_ARCH)
  1729.                 strcat (szTemp, "Archive");
  1730.             if (fiData.wAttr & _A_HIDDEN) {
  1731.                 if (strlen (szTemp) != 0)
  1732.                     strcat (szTemp, ", ");
  1733.                 strcat (szTemp, "Hidden");
  1734.             }
  1735.             if (fiData.wAttr & _A_SYSTEM) {
  1736.                 if (strlen (szTemp) != 0)
  1737.                     strcat (szTemp, ", ");
  1738.                 strcat (szTemp, "System");
  1739.             }
  1740.             if (fiData.wAttr & _A_RDONLY) {
  1741.                 if (strlen (szTemp) != 0)
  1742.                     strcat (szTemp, ", ");
  1743.                 strcat (szTemp, "Read Only");
  1744.             }
  1745.             SetDlgItemText (hwnd, IDD_INFOFLAGS, szTemp);
  1746.  
  1747.             return TRUE;
  1748.  
  1749.         case WM_COMMAND:
  1750.  
  1751.             switch (wParam) {
  1752.                 case IDOK:
  1753.                     EndDialog (hwnd, 1);
  1754.                     return TRUE;
  1755.             }
  1756.             break;
  1757.  
  1758.         case WM_CLOSE:
  1759.             EndDialog (hwnd, 0);
  1760.             return TRUE;
  1761.     }    
  1762.     return FALSE;    
  1763. }
  1764. //------------------------------------------------------------------------
  1765. //
  1766. // About box dialog procedure
  1767. //
  1768. //------------------------------------------------------------------------
  1769. BOOL FAR PASCAL AboutDlgProc (HWND hwnd, WORD message, WORD wParam, 
  1770.                                LONG lParam) {
  1771.  
  1772.     switch (message) {
  1773.  
  1774.         case WM_COMMAND:
  1775.  
  1776.             switch (wParam) {
  1777.  
  1778.                 case IDOK:
  1779.  
  1780.                     EndDialog (hwnd, 1);
  1781.                     return TRUE;
  1782.             }
  1783.             break;
  1784.  
  1785.         case WM_CLOSE:
  1786.             EndDialog (hwnd, 0);
  1787.             return TRUE;
  1788.     }
  1789.     return FALSE;    
  1790. }
  1791.  
  1792. //========================================================================
  1793. //
  1794. // Main Window Procedure.
  1795. //
  1796. //========================================================================
  1797. //------------------------------------------------------------------------
  1798. //
  1799. // Window Procedure
  1800. //
  1801. //------------------------------------------------------------------------
  1802. long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) {
  1803.  
  1804.     static        char      szPrograms [80];
  1805.     static        int       sWinHeight, sWinWidth, sOldBCnt;
  1806.     static        FARPROC    lpfnConfigDlgProc, lpfnCopyRenDlgProc;
  1807.     static        FARPROC    lpfnSetAttrDlgProc, lpfnAboutDlgProc;
  1808.     static        FARPROC    lpfnFileInfoDlgProc, lpfnMkDirDlgProc;
  1809.  
  1810.     char        szTemp [128], szSel [128];    
  1811.     char        szDrive [3], szDir [128], szName [9], szExt [5];
  1812.     int        i, sLBoxID, sNewCount, rc, sBHeight;
  1813.     RECT        rect;
  1814.     BOOL        bTemp;
  1815.  
  1816.     switch (message) {
  1817.     
  1818.         case WM_CREATE:
  1819.             //
  1820.             //Initialize Program ID string
  1821.             //
  1822.             GetProfileString ("windows", "Programs", "com exe", szPrograms,
  1823.                               sizeof (szPrograms));
  1824.             strupr (szPrograms);
  1825.             strcat (szPrograms, " ");
  1826.             //
  1827.             //Create thunks for dialog box and subclass procedures 
  1828.             //
  1829.             hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
  1830.  
  1831.             lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInstance);
  1832.             lpfnConfigDlgProc = MakeProcInstance (ConfigDlgProc, hInstance);
  1833.             lpfnCopyRenDlgProc = MakeProcInstance (CopyRenDlgProc, hInstance);
  1834.             lpfnMkDirDlgProc = MakeProcInstance (MkDirDlgProc, hInstance);
  1835.             lpfnSetAttrDlgProc = MakeProcInstance (SetAttrDlgProc, hInstance);
  1836.             lpfnFileInfoDlgProc = MakeProcInstance (FileInfoDlgProc, hInstance);
  1837.  
  1838.             lpfnListBoxSubclassProc = 
  1839.                     MakeProcInstance ((FARPROC) ListBoxSubclassProc, hInstance);
  1840.             lpfnEditBoxSubclassProc = 
  1841.                    MakeProcInstance ((FARPROC) EditBoxSubclassProc, hInstance);
  1842.             //
  1843.             //Create Child Windows (ListBoxes, Buttons, and Edit Box)
  1844.             //
  1845.             GetClientRect (hwnd, &rect);
  1846.             sWinHeight = rect.bottom - rect.top;
  1847.             sWinWidth = rect.right - rect.left;
  1848.     
  1849.             hwndDrvBox = CreateWindow ("listbox",
  1850.                           NULL,
  1851.                           WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  1852.                           WS_BORDER | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
  1853.                           5,                            //x Pos
  1854.                           5,                            //y Pos
  1855.                           sDrvBoxWidth,                 //x Size
  1856.                           LBoxHeight (sWinHeight),      //y Size
  1857.                           hwnd,                         //Parent handle
  1858.                           IDD_DRVBOX,                   //ID number
  1859.                           hInstance,
  1860.                           NULL);
  1861.             //
  1862.             // Subclass drive listbox
  1863.             //
  1864.             lpfnOldLBoxProc[0] = (FARPROC) GetWindowLong (hwndDrvBox, 
  1865.                                                           GWL_WNDPROC);
  1866.             SetWindowLong (hwndDrvBox, GWL_WNDPROC, 
  1867.                            (LONG) lpfnListBoxSubclassProc);
  1868.             //
  1869.             // Create directory listboxes
  1870.             //
  1871.             for (i = 0; i < NumLBoxes (sWinWidth) && i < LBOXMAX; i++) {
  1872.                hwndLBoxArray[i] = CreateWindow ("listbox",
  1873.                           NULL, 
  1874.                           WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  1875.                           WS_BORDER | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
  1876.                           LBoxPos (i),                  //x Pos
  1877.                           5,                            //y Pos
  1878.                           sLBoxWidth,                   //x Size
  1879.                           LBoxHeight (sWinHeight),      //y Size
  1880.                           hwnd,                         //Parent handle 
  1881.                           i+IDD_1STBOX,                 //ID number
  1882.                           hInstance,
  1883.                           NULL);
  1884.                sLBoxVisible++;
  1885.                 //
  1886.                 // Subclass each directory listbox
  1887.                 //
  1888.                 lpfnOldLBoxProc[i+1]=(FARPROC) GetWindowLong (hwndLBoxArray[i], 
  1889.                                                               GWL_WNDPROC);
  1890.                 SetWindowLong (hwndLBoxArray[i], GWL_WNDPROC, 
  1891.                                (LONG) lpfnListBoxSubclassProc);
  1892.             }
  1893.             //
  1894.             // Create Button windows
  1895.             //
  1896.             sBHeight = GetButtonHeight (rect.bottom);
  1897.  
  1898.             for (i = 0; i < sButtonCount; i++) 
  1899.                bsButtons [i].hwndButton = CreateWindow ("button",
  1900.                           fsFunctions [bsButtons [i].sFunction].szText,
  1901.                           WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
  1902.                           rect.right - BUTTONWIDTH - 5, //x Pos
  1903.                           5+(i * (sBHeight+5)),         //y Pos
  1904.                           BUTTONWIDTH,                  //x Size
  1905.                           sBHeight,                           //y Size
  1906.                           hwnd,                         //Parent handle
  1907.                           i+IDD_1STBUTTON,              //ID number
  1908.                           hInstance,
  1909.                           NULL);
  1910.  
  1911.             hwndScrollBar = CreateWindow ("scrollbar",
  1912.                        NULL,
  1913.                        WS_CHILD | WS_VISIBLE | SBS_HORZ,
  1914.                        5,                                      //Left of rect
  1915.                        rect.bottom - (2*sEditBoxHeight)-10,//y Pos
  1916.                        EBoxWidth (sLBoxVisible),             //x Size
  1917.                        sEditBoxHeight,                        //y Size
  1918.                        hwnd,                                   //Parent handle
  1919.                        IDD_SCROLLBAR,                          //ID number
  1920.                        hInstance,
  1921.                        NULL);
  1922.  
  1923.             hwndEditBox = CreateWindow ("edit",
  1924.                        NULL,
  1925.                        WS_CHILD | WS_VISIBLE | WS_BORDER |
  1926.                        ES_UPPERCASE | ES_LEFT,
  1927.                        5,                                      //x Pos
  1928.                        rect.bottom - sEditBoxHeight - 5,    //y Pos
  1929.                        EBoxWidth (sLBoxVisible),             //x Size
  1930.                        sEditBoxHeight,                      //y Size
  1931.                        hwnd,                                   //Parent handle
  1932.                        IDD_EDITBOX,                            //ID number
  1933.                        hInstance,
  1934.                        NULL);
  1935.             //
  1936.             // Subclass edit box
  1937.             //
  1938.             lpfnOldEditBoxProc = (FARPROC) GetWindowLong (hwndEditBox, 
  1939.                                                           GWL_WNDPROC);
  1940.             SetWindowLong (hwndEditBox, GWL_WNDPROC, 
  1941.                            (LONG) lpfnEditBoxSubclassProc);
  1942.  
  1943.             //
  1944.             // Fill drive box, then select the active drive
  1945.             //
  1946.             SendMessage (hwndDrvBox, LB_DIR, 0xC000, STRTOLP ("*.*"));
  1947.  
  1948.             FillListBoxes (hwnd);
  1949.  
  1950.             hwndFocusWin = hwndDrvBox;
  1951.  
  1952.             bDir = TRUE;
  1953.             bExecutable = EnableButtons (hwnd, FALSE, bDir);
  1954.             return 0;
  1955.  
  1956.  
  1957.         case WM_SETFOCUS:
  1958.             SetFocus (hwndFocusWin);
  1959.             break;
  1960.  
  1961.         case WM_SIZE:
  1962.             //
  1963.              //Check for changes in Window Width
  1964.              //
  1965.             sNewCount = NumLBoxes (LOWORD (lParam));
  1966.             if (sLBoxVisible > sNewCount) {
  1967.                 for (i = sNewCount; i <= sLBoxVisible; i++)
  1968.                 DestroyWindow (hwndLBoxArray[i]);
  1969.             } else {
  1970.                 if (sLBoxVisible < sNewCount && sLBoxVisible != LBOXMAX) 
  1971.                     for (i=sLBoxVisible; i<sNewCount && i<LBOXMAX;i++) {
  1972.                         hwndLBoxArray[i] = CreateWindow (
  1973.                                "listbox",
  1974.                                NULL,
  1975.                                WS_CHILD | WS_VISIBLE | 
  1976.                                WS_VSCROLL | WS_BORDER | 
  1977.                                LBS_NOTIFY | 
  1978.                                LBS_NOINTEGRALHEIGHT,
  1979.                                LBoxPos (i), 
  1980.                                5,           
  1981.                                sLBoxWidth,  
  1982.                                LBoxHeight (HIWORD (lParam)),
  1983.                                hwnd,                       
  1984.                                i+IDD_1STBOX,               
  1985.                                hInstance,
  1986.                                NULL);
  1987.                         //
  1988.                         // Subclass each new listbox
  1989.                         //
  1990.                         lpfnOldLBoxProc[i+1] = 
  1991.                             (FARPROC) GetWindowLong (
  1992.                                    hwndLBoxArray[i], 
  1993.                                    GWL_WNDPROC);
  1994.                         SetWindowLong (hwndLBoxArray[i], 
  1995.                               GWL_WNDPROC, 
  1996.                               (LONG) lpfnListBoxSubclassProc);
  1997.                          }
  1998.             }
  1999.             sWinWidth = LOWORD (lParam);
  2000.             //
  2001.             //Check for changes in Window Height
  2002.             //
  2003.             if (HIWORD (lParam) != (WORD) sWinHeight) {
  2004.                 for (i = 0; i < sLBoxVisible; i++)
  2005.                     SetWindowPos (hwndLBoxArray[i], NULL, 
  2006.                              0, 0, sLBoxWidth,
  2007.                              LBoxHeight (HIWORD (lParam)), 
  2008.                              SWP_NOMOVE);
  2009.                 SendMessage (hwndDrvBox, LB_SETTOPINDEX, 0,0L);
  2010.                 SetWindowPos (hwndDrvBox, NULL, 0, 0, 
  2011.                               sDrvBoxWidth,
  2012.                               LBoxHeight (HIWORD (lParam)), 
  2013.                               SWP_NOMOVE);
  2014.                 sWinHeight = HIWORD (lParam);
  2015.             }
  2016.             if (sNewCount != sLBoxVisible) {
  2017.                 sLBoxVisible = sNewCount;
  2018.                 FillListBoxes (hwnd);
  2019.             }
  2020.                SetWindowPos (hwndScrollBar, NULL, 5, 
  2021.                           HIWORD (lParam) - (2*sEditBoxHeight) - 10,
  2022.                           EBoxWidth (sLBoxVisible), sEditBoxHeight, NULL);
  2023.  
  2024.             SetWindowPos (hwndEditBox, NULL, 5, 
  2025.                           HIWORD (lParam) - sEditBoxHeight - 5,
  2026.                           EBoxWidth (sLBoxVisible), sEditBoxHeight, NULL);
  2027.             SetButtonPos (sWinHeight, sWinWidth);
  2028.             return 0;
  2029.  
  2030.  
  2031.         case WM_COMMAND:
  2032.             //
  2033.             // First, check for any menu selections.
  2034.             //
  2035.             switch (wParam) {
  2036.  
  2037.                 case IDM_OPEN:
  2038.                     if (bExecutable)
  2039.                         strcpy (szTemp, szMasterPath);
  2040.                     else {
  2041.                         _splitpath (szMasterPath, szDrive, szDir, szName, 
  2042.                                     szExt);
  2043.                         if (GetProfileString ("Extensions", szExt+1, "", 
  2044.                                               szSel, sizeof (szSel))) {
  2045.  
  2046.                             strcpy (szTemp, szSel);
  2047.                             szTemp [i = strcspn (szSel, "^")] = 0;
  2048.                             strcat (szTemp, szDrive);
  2049.                             strcat (szTemp, szDir);
  2050.                             strcat (szTemp, szName);
  2051.                             strcat (szTemp, szSel+i+1);    
  2052.                         } else {
  2053.                             strcpy (szTemp, szDefaultEditor);
  2054.                             strcat (szTemp, " ");
  2055.                             strcat (szTemp, szMasterPath);
  2056.                         }
  2057.                     }
  2058.                     WinExec (szTemp, SW_SHOW);
  2059.                     return 0;
  2060.  
  2061.                 case IDM_COPY:
  2062.                     strcpy (szFunction, "Copy");
  2063.                     if (DialogBox (hInstance, "CopyRen", hwnd, 
  2064.                                    lpfnCopyRenDlgProc)) {
  2065.                         if (bDir) {
  2066.                               if (CopyDir (hwnd, szDestPath, szMasterPath, 
  2067.                                          bIncDir))
  2068.                                 FillListBoxes (hwnd);
  2069.                         } else {
  2070.                               if (CopyFile (hwnd, szDestPath, szMasterPath))
  2071.                                 FillListBoxes (hwnd);
  2072.                         }
  2073.                     }
  2074.                     return 0;
  2075.  
  2076.                 case IDM_MOVE:
  2077.                     strcpy (szFunction, "Move");
  2078.                     if (DialogBox (hInstance, "CopyRen", hwnd, 
  2079.                                    lpfnCopyRenDlgProc)) {                        
  2080.                         if (bDir) {
  2081.                             if (CopyDir (hwnd, szDestPath, szMasterPath, 
  2082.                                          bIncDir)) 
  2083.                                 DeleteDir (hwnd, szMasterPath, bIncDir);
  2084.                         } else {
  2085.                             if (CopyFile (hwnd, szDestPath, szMasterPath)) 
  2086.                                 DeleteFile (hwnd, szMasterPath);
  2087.                         }
  2088.                         FillListBoxes (hwnd);
  2089.                     }
  2090.                     return 0;
  2091.  
  2092.  
  2093.                 case IDM_RENAME:
  2094.                     strcpy (szFunction, "Rename");
  2095.                     if (DialogBox (hInstance, "CopyRen", hwnd, 
  2096.                                    lpfnCopyRenDlgProc)) {
  2097.                         getcwd (szTemp, sizeof (szTemp));
  2098.                         if (bDir) chdir ("\\");
  2099.                         rc = rename (szMasterPath, szDestPath);
  2100.                         if (bDir) {
  2101.                             strcpy (szMasterPath, szDestPath);
  2102.                             chdir (szMasterPath);
  2103.                         }                        
  2104.                         if (rc) 
  2105.                             PrintError (hwnd, GetErrorCode (), szMasterPath);
  2106.  
  2107.                         FillListBoxes (hwnd);
  2108.                     }
  2109.                     return 0;
  2110.  
  2111.  
  2112.                 case IDM_MKDIR:
  2113.                     if (DialogBox (hInstance, "MkDir", hwnd, 
  2114.                                    lpfnMkDirDlgProc)) {
  2115.  
  2116.                        getcwd (szTemp, sizeof (szTemp));
  2117.                         if (chdir (szDestPath)) {
  2118.                             if (MakeDir (szDestPath)) 
  2119.                                 FillListBoxes (hwnd);
  2120.                             else
  2121.                                 PrintError (hwnd, GetErrorCode(), szDestPath);
  2122.                         } else {
  2123.                             chdir (szTemp);
  2124.                             strcpy (szTemp, "The directory: ");
  2125.                             strcat (szTemp, szDestPath);
  2126.                             strcat (szTemp, " already exists.");
  2127.                            MessageBox (hwnd, szTemp, szAppName, MB_OK);
  2128.                         }
  2129.                     }
  2130.                     return 0;
  2131.  
  2132.  
  2133.                 case IDM_ATTRIB:
  2134.                     if (DialogBox (hInstance, "SetAttr", hwnd, 
  2135.                                    lpfnSetAttrDlgProc)) 
  2136.                         FillListBoxes (hwnd);
  2137.                     return 0;
  2138.  
  2139.  
  2140.                 case IDM_INFO:
  2141.                     DialogBox (hInstance, "FileInfo", hwnd, 
  2142.                                lpfnFileInfoDlgProc);
  2143.                     return 0;
  2144.  
  2145.  
  2146.                 case IDM_DELETE:
  2147.                     //
  2148.                     // Before deleteing file or directory, 
  2149.                     // display confirmation box if necessary.
  2150.                     //
  2151.                     strcpy (szTemp, "Do you wish to delete the ");
  2152.                     if (bDir) {
  2153.                         strcat (szTemp, "directory:\n");
  2154.                         bTemp = bConfirmDirDel;
  2155.                     } else {
  2156.                         strcat (szTemp, "file:\n");
  2157.                         bTemp = bConfirmFileDel;
  2158.                     }
  2159.                     strcat (szTemp, szMasterPath);
  2160.                     if (bTemp)
  2161.                         if (MessageBox (hwnd, szTemp, szAppName, 
  2162.                                         MB_YESNO) != IDYES) 
  2163.                             return 0;
  2164.                     //
  2165.                     // Delete file or directory.
  2166.                     //
  2167.                     if (bDir) {
  2168.                         strcpy (szTemp, szMasterPath);
  2169.                         if (strlen (szTemp) != 3)
  2170.                             *strrchr (szTemp, '\\') = '\0';
  2171.                         chdir (szTemp);
  2172.                         if (DeleteDir (hwnd, szMasterPath, TRUE))
  2173.                             FillListBoxes (hwnd);
  2174.                     } else 
  2175.                         if (DeleteFile (hwnd, szMasterPath))
  2176.                             FillListBoxes (hwnd);
  2177.                     return 0;
  2178.  
  2179.  
  2180.                 case IDM_CONFIG:
  2181.                     sOldBCnt = sButtonCount;
  2182.                     if (DialogBox (hInstance, "Config", hwnd, 
  2183.                                    lpfnConfigDlgProc)) {
  2184.  
  2185.                         if (sOldBCnt > sButtonCount) {
  2186.                             for (i = sOldBCnt-1; i >= sButtonCount; i--) {
  2187.                              DestroyWindow (bsButtons[i].hwndButton);
  2188.                              bsButtons[i].hwndButton = 0;
  2189.                             }    
  2190.                         }
  2191.                         if (sOldBCnt < sButtonCount) {
  2192.  
  2193.                             sBHeight = GetButtonHeight (sWinHeight);
  2194.  
  2195.                             for (i = sOldBCnt; i < sButtonCount; i++) 
  2196.                                bsButtons [i].hwndButton = 
  2197.                                  CreateWindow ("button",
  2198.                                        fsFunctions [bsButtons [i].sFunction].szText,
  2199.                                       WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
  2200.                                     sWinWidth - BUTTONWIDTH - 5, //x Pos
  2201.                                    5+(i * (sBHeight+5)),        //y Pos
  2202.                                       BUTTONWIDTH,                 //x Size
  2203.                                     sBHeight,                    //y Size
  2204.                                       hwnd,                        //Parent handle
  2205.                                     i+IDD_1STBUTTON,             //ID number
  2206.                                    hInstance,
  2207.                                        NULL);
  2208.                         }
  2209.                         if (sOldBCnt != sButtonCount) {
  2210.                             i = sWinWidth--;
  2211.                             SendMessage (hwnd, WM_SIZE, 0, 
  2212.                                          MAKELONG (i, sWinHeight));
  2213.                             InvalidateRect (hwnd, 0, FALSE);
  2214.                         }
  2215.                         if (bDir)
  2216.                             bExecutable = EnableButtons (hwnd, FALSE, bDir);
  2217.                         else    
  2218.                             bExecutable = EnableButtons (hwnd, 
  2219.                                       IsProgram (szPrograms, szMasterPath), 
  2220.                                      bDir);
  2221.                         FillListBoxes (hwnd);
  2222.  
  2223.                         itoa (sSearchFlags, szTemp, 10);
  2224.                         WritePrivateProfileString (szAppName, "IncFlags", 
  2225.                                                    szTemp, szProfileName);
  2226.                         itoa (bDirFirst, szTemp, 10);
  2227.                         WritePrivateProfileString (szAppName, "DirFirst", 
  2228.                                                    szTemp, szProfileName);
  2229.                         itoa (bConfirmFileDel, szTemp, 10);
  2230.                         WritePrivateProfileString (szAppName, "ConfFileDel", 
  2231.                                                    szTemp, szProfileName);
  2232.                         itoa (bConfirmDirDel, szTemp, 10);
  2233.                         WritePrivateProfileString (szAppName, "ConfDirDel", 
  2234.                                                    szTemp, szProfileName);
  2235.                         WritePrivateProfileString (szAppName, "DefaultEditor", 
  2236.                                                    szDefaultEditor, 
  2237.                                                    szProfileName);
  2238.                         itoa (sButtonCount, szTemp, 10);
  2239.                         WritePrivateProfileString (szAppName, "NumberButtons", 
  2240.                                                    szTemp, szProfileName);
  2241.  
  2242.                         for (i = 0; i < BUTTONMAX; i++) {
  2243.                             strcpy (szTemp, "Button");
  2244.                             itoa (i, szSel, 10);
  2245.                             strcat (szTemp, szSel);
  2246.                             itoa (bsButtons[i].sFunction, szSel, 10);                
  2247.                             WritePrivateProfileString(szAppName, szTemp, szSel, 
  2248.                                                       szProfileName);
  2249.                         }
  2250.                     }
  2251.                           return 0;
  2252.  
  2253.                 case IDM_ABOUT:
  2254.                     DialogBox (hInstance, "About", hwnd, lpfnAboutDlgProc);
  2255.                           return 0;
  2256.  
  2257.                 case IDM_EXIT:
  2258.                     SendMessage (hwnd, WM_CLOSE, 0, 0);
  2259.                        return 0;
  2260.             }
  2261.             //
  2262.             // Check Editbox
  2263.             //
  2264.             if (wParam == IDD_EDITBOX && HIWORD (lParam) == EN_KILLFOCUS) {
  2265.                 GetWindowText (hwndEditBox, szTemp, sizeof (szTemp));
  2266.                 if (strcmp (szTemp, szMasterPath))
  2267.                     SendMessage (hwnd, WUM_SETPATH, 0, 0L);
  2268.             }
  2269.             //
  2270.             // Check Drive selection Listbox
  2271.             //
  2272.             if (wParam == IDD_DRVBOX && 
  2273.                 HIWORD (lParam) == LBN_SELCHANGE) {
  2274.                 SendMessage (hwndDrvBox, LB_GETTEXT,
  2275.                              (WORD) SendMessage (hwndDrvBox, LB_GETCURSEL, 
  2276.                                                  0, 0L),
  2277.                              STRTOLP (szMasterPath)); 
  2278.  
  2279.                 getcwd (szSel, sizeof (szSel));
  2280.                 _chdrive (szMasterPath [2] - 'a' + 1);
  2281.                 FillListBoxes (hwnd);            
  2282.             }
  2283.             //    
  2284.             // Check directory listboxes
  2285.             //
  2286.             if (wParam >= IDD_1STBOX && 
  2287.                 wParam < (WORD) IDD_1STBOX+sLBoxVisible) {
  2288.  
  2289.                 sLBoxID = TranslateID (wParam);
  2290.  
  2291.                 switch (HIWORD (lParam)) {
  2292.     
  2293.                     case LBN_SELCHANGE:
  2294.  
  2295.                         DlgDirSelect (hwnd, szMasterPath, IDD_DRVBOX);
  2296.                         strcat (szMasterPath, "\\");
  2297.  
  2298.                         bDir = FALSE;
  2299.                         for (i = 0; i < sLBoxCount; i++) {
  2300.                             if (i < sLBoxID - IDD_1STBOX) {
  2301.                                 GetLBoxText (i, szSel);
  2302.                                 strncat (szMasterPath, szSel+1, 
  2303.                                          strlen (szSel)-2);
  2304.                                 strcat (szMasterPath, "\\");
  2305.     
  2306.                             } else if (i == sLBoxID - IDD_1STBOX) {
  2307.                                 GetLBoxText (i, szSel);
  2308.                                 if (szSel[0]=='[' && 
  2309.                                     szSel[strlen(szSel)-1] == ']') {
  2310.                                         strncat (szMasterPath, szSel+1, 
  2311.                                                  strlen (szSel)-2);
  2312.                                         bDir = TRUE;
  2313.                                 } else 
  2314.                                     strcat (szMasterPath, szSel);
  2315.                             } else
  2316.                               SendLBoxMsg (i, LB_RESETCONTENT, 0, 0L);
  2317.                         }
  2318.                          i = wParam - IDD_1STBOX;
  2319.                         if (bDir) {
  2320.                             chdir (szMasterPath);
  2321.                             if (((i != sLBoxVisible - 2) && sLBoxVStart > 0)
  2322.                                   || (i == sLBoxVisible - 1)) {
  2323.                                 FillListBoxes (hwnd);
  2324.                             } else {
  2325.                                 strcpy (szTemp, szMasterPath);
  2326.                                 strcat (szTemp, "\\");
  2327.                                 if (sLBoxID - IDD_1STBOX < sLBoxCount)
  2328.                                     FillListBox (hwnd, szTemp, 
  2329.                                                  sLBoxID - IDD_1STBOX + 1);
  2330.                             }
  2331.                         } else
  2332.                             if ((i != sLBoxVisible - 1) && sLBoxVStart > 0) {
  2333.                                 *strrchr (szMasterPath, '\\') = '\0';
  2334.                                 chdir (szMasterPath);
  2335.                                 i = FillListBoxes (hwnd);
  2336.                                 strcat (szMasterPath, "\\");
  2337.                                 strcat (szMasterPath, szSel);
  2338.                                 SendLBoxMsg (i, LB_SELECTSTRING, -1, 
  2339.                                              STRTOLP (szSel));
  2340.                             }
  2341.  
  2342.                        SetWindowText (hwndEditBox, szMasterPath);
  2343.  
  2344.                         if (bDir)
  2345.                             bExecutable = EnableButtons (hwnd, FALSE, bDir);
  2346.                         else    
  2347.                             bExecutable = EnableButtons (hwnd, 
  2348.                                               IsProgram (szPrograms, 
  2349.                                                          szMasterPath), 
  2350.                                               bDir);
  2351.                          break;
  2352.  
  2353.                   case LBN_DBLCLK:
  2354.                         if (!bDir) 
  2355.                             SendMessage (hwnd, WM_COMMAND, IDM_OPEN, 0L);
  2356.                         break;
  2357.                 }
  2358.             }
  2359.             //    
  2360.             // Check Buttons
  2361.             //
  2362.             if (wParam >= IDD_1STBUTTON && 
  2363.                 wParam < (WORD) IDD_1STBUTTON+sButtonCount) {
  2364.                 //
  2365.                 // Simulate a menu message by sending a WM_COMMAND message
  2366.                 // to the client window.  
  2367.                 //
  2368.                 if (HIWORD (lParam) == BN_CLICKED) {
  2369.                     i = wParam - IDD_1STBUTTON;
  2370.                     SendMessage (hwnd, WM_COMMAND, 
  2371.                                fsFunctions [bsButtons[i].sFunction].sFunction, 
  2372.                                0L);
  2373.                 }
  2374.             }
  2375.             break;
  2376.  
  2377.         case WM_HSCROLL:
  2378.  
  2379.             sNewCount = sLBoxVStart;
  2380.  
  2381.             switch (wParam) {
  2382.                 case SB_TOP:
  2383.                     ScrollLBoxes (-sLBoxVStart);
  2384.                     break;
  2385.  
  2386.                 case SB_BOTTOM:
  2387.                     i = GetDirDepth ();
  2388.                     ScrollLBoxes (i - sLBoxVStart - sLBoxVisible);    
  2389.                     break;
  2390.  
  2391.                 case SB_LINEDOWN:
  2392.                     ScrollLBoxes (1);
  2393.                     break;
  2394.  
  2395.                 case SB_LINEUP:
  2396.                     ScrollLBoxes (-1);
  2397.                     break;
  2398.  
  2399.                 case SB_PAGEDOWN:
  2400.                     i = GetDirDepth ();
  2401.                     ScrollLBoxes (sLBoxVisible);
  2402.                     break;
  2403.  
  2404.                 case SB_PAGEUP:
  2405.                     ScrollLBoxes (-sLBoxVisible);
  2406.                     break;
  2407.  
  2408.                 case SB_THUMBPOSITION:
  2409.                     ScrollLBoxes (LOWORD (lParam) - sNewCount);
  2410.                     break;
  2411.             }            
  2412.             if (sLBoxVStart != sNewCount) 
  2413.                 RefreshListBoxes (hwnd);                
  2414.             break;
  2415.  
  2416.         case WUM_SETPATH:
  2417.             GetWindowText (hwndEditBox, szTemp, sizeof (szTemp));
  2418.  
  2419.             _fullpath (szSel, szTemp, sizeof (szSel));
  2420.  
  2421.             if (_chdrive ((int) szSel[0] - '@') == -1)
  2422.                 return 0;
  2423.  
  2424.             if (chdir (szSel) == 0) {
  2425.                 strcpy (szMasterPath, szSel);
  2426.                 FillListBoxes (hwnd);
  2427.             } else {    
  2428.                 _splitpath (szSel, szDrive, szDir, szName, szExt);
  2429.                 strlwr (szName);
  2430.                 *strrchr (szSel, '\\') = '\0';
  2431.  
  2432.                 if (chdir (szSel) == 0) {
  2433.                     strcpy (szMasterPath, szSel);
  2434.                     sLBoxID = FillListBoxes (hwnd);
  2435.                     strcpy (szSel, szName);
  2436.                     strcat (szSel, szExt);
  2437.                     strlwr (szSel);
  2438.                     SendLBoxMsg (sLBoxID, LB_SELECTSTRING, 
  2439.                                  -1, STRTOLP (szSel));
  2440.                 }
  2441.             }
  2442.             break;
  2443.  
  2444.         case WM_DESTROY:
  2445.             //
  2446.             //Save window position and size in profile
  2447.             //
  2448.             if (IsZoomed (hwnd)) {
  2449.                 WritePrivateProfileString (szAppName, "Zoom", "1", 
  2450.                                            szProfileName);
  2451.             } else if (!IsIconic (hwnd)) {
  2452.                 WritePrivateProfileString (szAppName, "Zoom", "0", 
  2453.                                            szProfileName);
  2454.                 GetWindowRect (hwnd, &rect);
  2455.                 itoa (rect.left, szTemp, 10);
  2456.                 WritePrivateProfileString (szAppName, "x", szTemp, 
  2457.                                            szProfileName);
  2458.                 itoa (rect.top, szTemp, 10);
  2459.                 WritePrivateProfileString (szAppName, "y", szTemp, 
  2460.                                            szProfileName);
  2461.                 itoa (rect.right - rect.left, szTemp, 10);
  2462.                 WritePrivateProfileString (szAppName, "cx", szTemp, 
  2463.                                            szProfileName);
  2464.                 itoa (rect.bottom - rect.top, szTemp, 10);
  2465.                 WritePrivateProfileString (szAppName, "cy", szTemp, 
  2466.                                            szProfileName);
  2467.             }
  2468.             PostQuitMessage (0);
  2469.             return 0;
  2470.     }
  2471.     return DefWindowProc (hwnd, message, wParam, lParam);
  2472. }
  2473.